r17263 by jghali - first part of win32 printing system update

scribus-commit scribus-commit at lists.scribus.net
Tue Jan 31 00:04:41 UTC 2012


Author: jghali
Date: Tue Jan 31 00:04:40 2012
New Revision: 17263

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=17263
Log:
first part of win32 printing system update

Modified:
    trunk/Scribus/scribus/scpageoutput.cpp
    trunk/Scribus/scribus/scpageoutput.h
    trunk/Scribus/scribus/scpainterex_cairo.cpp
    trunk/Scribus/scribus/scpainterex_cairo.h
    trunk/Scribus/scribus/scpainterex_ps2.cpp
    trunk/Scribus/scribus/scpainterex_ps2.h
    trunk/Scribus/scribus/scpainterexbase.h

Modified: trunk/Scribus/scribus/scpageoutput.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17263&path=/trunk/Scribus/scribus/scpageoutput.cpp
==============================================================================
--- trunk/Scribus/scribus/scpageoutput.cpp (original)
+++ trunk/Scribus/scribus/scpageoutput.cpp Tue Jan 31 00:04:40 2012
@@ -304,7 +304,10 @@
 //		painter->rotate(item->rotation());
 	}
 	painter->rotate(item->rotation());
+	painter->setBlendModeFill(item->fillBlendmode());
 	painter->setLineWidth(item->lineWidth());
+	if (item->isGroup())
+		return;
 	if (item->GrType == 8)
 	{
 		QString pat = item->pattern();
@@ -324,39 +327,78 @@
 			QTransform patternTransform;
 			ScPattern& pattern = m_doc->docPatterns[item->pattern()];
 			double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY;
+			bool   patternMirrorX, patternMirrorY;
 			item->patternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
-			patternTransform.translate(patternOffsetX, patternOffsetY);
-			patternTransform.rotate(patternRotation);
-			patternTransform.shear(patternSkewX, patternSkewY);
-			patternTransform.scale(pattern.scaleX, pattern.scaleY);
-			patternTransform.scale(patternScaleX / 100.0 , patternScaleY / 100.0);
-			painter->setPattern(&pattern, patternTransform);
+			item->patternFlip(patternMirrorX, patternMirrorY);
+			painter->setPattern(&pattern, patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, patternMirrorX, patternMirrorY);
 			painter->setFillMode(ScPainterExBase::Pattern);
 		}
 	}
+	else if (item->GrType == 9)
+	{
+		painter->setFillMode(ScPainterExBase::Gradient);
+		FPoint pG1 = FPoint(0, 0);
+		FPoint pG2 = FPoint(item->width(), 0);
+		FPoint pG3 = FPoint(item->width(), item->height());
+		FPoint pG4 = FPoint(0, item->height());
+		ScColorShade col1(m_doc->PageColors[item->GrColorP1], item->GrCol1Shade);
+		ScColorShade col2(m_doc->PageColors[item->GrColorP2], item->GrCol2Shade);
+		ScColorShade col3(m_doc->PageColors[item->GrColorP3], item->GrCol3Shade);
+		ScColorShade col4(m_doc->PageColors[item->GrColorP4], item->GrCol4Shade);
+		painter->set4ColorGeometry(pG1, pG2, pG3, pG4, item->GrControl1, item->GrControl2, item->GrControl3, item->GrControl4);
+		painter->set4ColorColors(col1, col2, col3, col4);
+	}
 	else if (item->GrType != 0)
 	{
-		painter->setFillMode(ScPainterExBase::Gradient);
-		painter->m_fillGradient = VGradientEx(item->fill_gradient, *m_doc);
-		QTransform grm;
-		grm.rotate(item->rotation());
-		FPointArray gra;
-		switch (item->GrType)
-		{
-			case 1:
-			case 2:
-			case 3:
-			case 4:
-			case 6:
-				gra.setPoints(2, item->GrStartX, item->GrStartY, item->GrEndX, item->GrEndY);
-				gra.map(grm);
-				painter->setGradient(VGradientEx::linear, gra.point(0), gra.point(1));
-				break;
-			case 5:
-			case 7:
-				gra.setPoints(2, item->GrStartX, item->GrStartY, item->GrEndX, item->GrEndY);
-				painter->setGradient(VGradientEx::radial, gra.point(0), gra.point(1), gra.point(0));
-				break;
+		QString gradientVal = item->gradient();
+		if ((!gradientVal.isEmpty()) && (!m_doc->docGradients.contains(gradientVal)))
+			gradientVal = "";
+		if (!(gradientVal.isEmpty()) && (m_doc->docGradients.contains(gradientVal)))
+			painter->m_fillGradient = VGradientEx(m_doc->docGradients[gradientVal], *m_doc);
+		if ((painter->m_fillGradient.Stops() < 2) && (item->GrType < 9)) // fall back to solid filling if there are not enough colorstops in the gradient.
+		{
+			if (item->fillColor() != CommonStrings::None)
+			{
+				painter->setBrush( ScColorShade(m_doc->PageColors[item->fillColor()], (int) item->fillShade()) );
+				painter->setFillMode(ScPainterExBase::Solid);
+			}
+			else
+				painter->setFillMode(ScPainterExBase::None);
+		}
+		else
+		{
+			FPoint fpStart(item->GrStartX, item->GrStartY), fpEnd(item->GrEndX, item->GrEndY);
+			FPoint fpFocal(item->GrFocalX, item->GrFocalY);
+			painter->setFillMode(ScPainterExBase::Gradient);
+			painter->m_fillGradient = VGradientEx(item->fill_gradient, *m_doc);
+			switch (item->GrType)
+			{
+				case 1:
+				case 2:
+				case 3:
+				case 4:
+				case 6:
+					painter->setGradient(VGradientEx::linear, fpStart, fpEnd, fpStart, item->GrScale, item->GrSkew);
+					break;
+				case 5:
+				case 7:
+					painter->setGradient(VGradientEx::radial, fpStart, fpEnd, fpFocal, item->GrScale, item->GrSkew);
+					break;
+				case 10:
+					painter->setFillMode(ScPainterExBase::Gradient);
+					painter->setDiamondGeometry(FPoint(0, 0), FPoint(item->width(), 0), FPoint(item->width(), item->height()), FPoint(0, item->height()), 
+					                            item->GrControl1, item->GrControl2, item->GrControl3, item->GrControl4, item->GrControl5);
+					break;
+				case 11:
+				case 13:
+					painter->setFillMode(ScPainterExBase::Gradient);
+					painter->setMeshGradient(FPoint(0, 0), FPoint(item->width(), 0), FPoint(item->width(), item->height()), FPoint(0, item->height()), item->meshGradientArray);
+					break;
+				case 12:
+					painter->setFillMode(ScPainterExBase::Gradient);
+					painter->setMeshGradient(FPoint(0, 0), FPoint(item->width(), 0), FPoint(item->width(), item->height()), FPoint(0, item->height()), item->meshGradientPatches);
+					break;
+			}
 		}
 	}
 	else
@@ -387,48 +429,157 @@
 	painter->setBrushOpacity(1.0 - item->fillTransparency());
 	painter->setPenOpacity(1.0 - item->lineTransparency());
 	painter->setFillRule(item->fillRule);
+
+	if ((item->GrMask == 1) || (item->GrMask == 2) || (item->GrMask == 4) || (item->GrMask == 5))
+	{
+		QString gradientMaskVal = item->gradientMaskVal;
+		FPoint fpMaskStart(item->GrMaskStartX, item->GrMaskStartY);
+		FPoint fpMaskEnd(item->GrMaskEndX, item->GrMaskEndY);
+		FPoint fpMaskFocal(item->GrMaskFocalX, item->GrMaskFocalY);
+		if ((item->GrMask == 1) || (item->GrMask == 2))
+			painter->setMaskMode(1);
+		else
+			painter->setMaskMode(3);
+		if ((!gradientMaskVal.isEmpty()) && (!m_doc->docGradients.contains(gradientMaskVal)))
+			gradientMaskVal = "";
+		if (!(gradientMaskVal.isEmpty()) && (m_doc->docGradients.contains(gradientMaskVal)))
+			painter->m_maskGradient = VGradientEx(m_doc->docGradients[gradientMaskVal], *m_doc);
+		if ((item->GrMask == 1) || (item->GrMask == 4))
+			painter->setGradientMask(VGradientEx::linear, fpMaskStart, fpMaskEnd, fpMaskStart, item->GrMaskScale, item->GrMaskSkew);
+		else
+			painter->setGradientMask(VGradientEx::radial, fpMaskStart, fpMaskEnd, fpMaskFocal, item->GrMaskScale, item->GrMaskSkew);
+	}
+	else if ((item->GrMask == 3) || (item->GrMask == 6) || (item->GrMask == 7) || (item->GrMask == 8))
+	{
+		QString patternMaskVal = item->patternMaskVal;
+		if ((patternMaskVal.isEmpty()) || (!m_doc->docPatterns.contains(patternMaskVal)))
+			painter->setMaskMode(0);
+		else
+		{
+			painter->setPatternMask(&m_doc->docPatterns[patternMaskVal], item->patternMaskScaleX, item->patternMaskScaleY, item->patternMaskOffsetX, item->patternMaskOffsetY, 
+				                    item->patternMaskRotation, item->patternMaskSkewX, item->patternMaskSkewY, item->patternMaskMirrorX, item->patternMaskMirrorY);
+			if (item->GrMask == 3)
+				painter->setMaskMode(2);
+			else if (item->GrMask == 6)
+				painter->setMaskMode(4);
+			else if (item->GrMask == 7)
+				painter->setMaskMode(5);
+			else
+				painter->setMaskMode(6);
+		}
+	}
+	else
+		painter->setMaskMode(0);
 }
 
 void ScPageOutput::drawItem_Post( PageItem* item, ScPainterExBase* painter )
 {
-	bool doStroke=true;
-	if ( item->itemType() == PageItem::PathText || item->itemType() == PageItem::PolyLine || item->itemType() == PageItem::Line )
-		doStroke=false;
-	if ((doStroke))
-	{
-		if (item->lineColor() != CommonStrings::None)
-		{
-			ScColorShade tmp(m_doc->PageColors[item->lineColor()], (int) item->lineShade());
-			painter->setPen(tmp, item->lineWidth(), item->PLineArt, item->PLineEnd, item->PLineJoin);
-			if (item->DashValues.count() != 0)
-				painter->setDash(item->DashValues, item->DashOffset);
-		}
-		else
-			painter->setLineWidth(0);
-		if (!item->isTableItem)
-		{
-			painter->setupPolygon(&item->PoLine);
-			if (item->NamedLStyle.isEmpty())
-				painter->strokePath();
+	bool doStroke = true;
+	if (!item->isGroup())
+	{
+		painter->setMaskMode(0);
+		if ( item->itemType() == PageItem::PathText || item->itemType() == PageItem::PolyLine || item->itemType() == PageItem::Line )
+			doStroke = false;
+		if ((doStroke))
+		{
+			painter->setBlendModeStroke(item->lineBlendmode());
+			painter->setPenOpacity(1.0 - item->lineTransparency());
+			if ((item->lineColor() != CommonStrings::None)|| (!item->strokePattern().isEmpty()) || (item->strokeGradientType() > 0))
+			{
+				ScColorShade tmp(m_doc->PageColors[item->lineColor()], (int) item->lineShade());
+				painter->setPen(tmp, item->lineWidth(), item->PLineArt, item->PLineEnd, item->PLineJoin);
+				if (item->DashValues.count() != 0)
+					painter->setDash(item->DashValues, item->DashOffset);
+			}
 			else
-			{
-				multiLine ml = m_doc->MLineStyles[item->NamedLStyle];
-				for (int it = ml.size()-1; it > -1; it--)
+				painter->setLineWidth(0);
+			if (!item->isTableItem)
+			{
+				if ((item->itemType() == PageItem::LatexFrame) || (item->itemType() == PageItem::ImageFrame) || (item->itemType() == PageItem::OSGFrame))
+					painter->setupPolygon(&item->PoLine);
+				if (item->NamedLStyle.isEmpty())
 				{
-					const SingleLine& sl = ml[it];
-					if ((sl.Color != CommonStrings::None) && (sl.Width != 0))
+					QString patternStrokeVal = item->strokePattern();
+					if ((!patternStrokeVal.isEmpty()) && (m_doc->docPatterns.contains(patternStrokeVal)))
 					{
-						ScColorShade tmp(m_doc->PageColors[sl.Color], sl.Shade);
-						painter->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash),
-								static_cast<Qt::PenCapStyle>(sl.LineEnd),
-								static_cast<Qt::PenJoinStyle>(sl.LineJoin));
+						if (item->patternStrokePath)
+						{
+							QPainterPath guidePath = item->PoLine.toQPainterPath(false);
+							drawStrokePattern(item, painter, guidePath);
+						}
+						else
+						{
+							painter->setPattern(&m_doc->docPatterns[patternStrokeVal], item->patternStrokeScaleX, item->patternStrokeScaleY, item->patternStrokeOffsetX, item->patternStrokeOffsetY, item->patternStrokeRotation, item->patternStrokeSkewX, item->patternStrokeSkewY, item->patternStrokeMirrorX, item->patternStrokeMirrorY);
+							painter->setStrokeMode(ScPainterExBase::Pattern);
+							painter->strokePath();
+						}
+					}
+					else if (item->strokeGradientType() > 0)
+					{
+						QString gradientStrokeVal = item->strokeGradient();
+						if ((!gradientStrokeVal.isEmpty()) && (!m_doc->docGradients.contains(gradientStrokeVal)))
+							gradientStrokeVal = "";
+						if (!(gradientStrokeVal.isEmpty()) && (m_doc->docGradients.contains(gradientStrokeVal)))
+							painter->m_strokeGradient = VGradientEx(m_doc->docGradients[gradientStrokeVal], *m_doc);
+						if (painter->m_strokeGradient.Stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient.
+						{
+							if (item->lineColor() != CommonStrings::None)
+							{
+								ScColorShade strokeColor(m_doc->PageColors[item->lineColor()], item->lineShade());
+								painter->setBrush(strokeColor);
+								painter->setStrokeMode(ScPainterExBase::Solid);
+							}
+							else
+								painter->setStrokeMode(ScPainterExBase::None);
+						}
+						else
+						{
+							FPoint fpStart(item->GrStrokeStartX, item->GrStrokeStartY);
+							FPoint fpEnd(item->GrStrokeEndX, item->GrStrokeEndY);
+							FPoint fpFocal(item->GrStrokeFocalX, item->GrStrokeFocalY);
+							painter->setStrokeMode(ScPainterExBase::Gradient);
+							painter->m_strokeGradient = VGradientEx(item->stroke_gradient, *m_doc);
+							if (item->GrTypeStroke == 6)
+								painter->setGradient(VGradientEx::linear, fpStart, fpEnd, fpStart, item->GrStrokeScale, item->GrStrokeSkew);
+							else
+								painter->setGradient(VGradientEx::radial, fpStart, fpEnd, fpFocal, item->GrStrokeScale, item->GrStrokeSkew);
+						}
+						painter->strokePath();
+					}
+					else if (item->lineColor() != CommonStrings::None)
+					{
+						ScColorShade scColor(m_doc->PageColors[item->lineColor()], item->lineShade());
+						painter->setStrokeMode(ScPainterExBase::Solid);
+						painter->setPen(scColor, item->lineWidth(), item->PLineArt, item->PLineEnd, item->PLineJoin);
+						if (item->DashValues.count() != 0)
+							painter->setDash(item->DashValues, item->DashOffset);
 						painter->strokePath();
 					}
 				}
-			}
-		}
-	}
-//	item->Tinput = false;
+				else
+				{
+					multiLine ml = m_doc->MLineStyles[item->NamedLStyle];
+					for (int it = ml.size()-1; it > -1; it--)
+					{
+						const SingleLine& sl = ml[it];
+						if ((sl.Color != CommonStrings::None) && (sl.Width != 0))
+						{
+							ScColorShade tmp(m_doc->PageColors[sl.Color], sl.Shade);
+							painter->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash),
+									static_cast<Qt::PenCapStyle>(sl.LineEnd),
+									static_cast<Qt::PenJoinStyle>(sl.LineJoin));
+							painter->strokePath();
+						}
+					}
+				}
+			}
+			painter->setBlendModeStroke(0);
+		}
+	}
+	painter->setFillMode(ScPainterExBase::Solid);
+	painter->setBlendModeFill(0);
+	painter->setStrokeMode(ScPainterExBase::Solid);
+	painter->setBlendModeStroke(0);
 	painter->restore();
 }
 
@@ -768,6 +919,11 @@
 		painter->restore();
 	}
 	painter->restore();
+}
+
+void ScPageOutput::drawStrokePattern(PageItem* item, ScPainterExBase* painter, const QPainterPath& path)
+{
+
 }
 
 void ScPageOutput::drawItem_ImageFrame( PageItem_ImageFrame* item, ScPainterExBase* painter, const QRect& clip  )

Modified: trunk/Scribus/scribus/scpageoutput.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17263&path=/trunk/Scribus/scribus/scpageoutput.h
==============================================================================
--- trunk/Scribus/scribus/scpageoutput.h (original)
+++ trunk/Scribus/scribus/scpageoutput.h Tue Jan 31 00:04:40 2012
@@ -68,7 +68,8 @@
 
 	virtual void drawGlyphs(PageItem* item, ScPainterExBase *painter, const CharStyle& style, GlyphLayout& glyphs, const QRect& clip);
 	virtual void drawItem_Embedded( PageItem* item, ScPainterExBase *p, const QRect& clip, const CharStyle& style, PageItem* cembedded);
-	virtual void drawPattern( PageItem* item, ScPainterExBase* painter, const QRect& clip);
+	virtual void drawPattern(PageItem* item, ScPainterExBase* painter, const QRect& clip);
+	virtual void drawStrokePattern(PageItem* item, ScPainterExBase* painter, const QPainterPath& path);
 	
 	virtual void drawItem_ImageFrame( PageItem_ImageFrame* item, ScPainterExBase* painter, const QRect& clip );
 	virtual void drawItem_Line( PageItem_Line* item, ScPainterExBase* painter, const QRect& clip);

Modified: trunk/Scribus/scribus/scpainterex_cairo.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17263&path=/trunk/Scribus/scribus/scpainterex_cairo.cpp
==============================================================================
--- trunk/Scribus/scribus/scpainterex_cairo.cpp (original)
+++ trunk/Scribus/scribus/scpainterex_cairo.cpp Tue Jan 31 00:04:40 2012
@@ -1,523 +1,1161 @@
-/*
-For general Scribus (>=1.3.2) copyright and licensing information please refer
-to the COPYING file provided with the program. Following this notice may exist
-a copyright and/or license notice that predates the release of Scribus 1.3.2
-for which a new license (GPL+exception) is in place.
-*/
-
-#include <cmath>
-#include "scpainterex_cairo.h"
-#include "sccolorengine.h"
-#include "util.h"
-
-ScPainterEx_Cairo::ScPainterEx_Cairo( cairo_t* context, QRect& rect,  ScribusDoc* doc, bool gray ) : ScPainterExBase()
-{
-	m_doc    = doc;
-	m_width  = rect.width();
-	m_height = rect.height();
-	m_strokeColor = ScColorShade( QColor(0,0,0), 100 );
-	m_fillColor = ScColorShade( QColor(0,0,0), 100 );
-	m_fillTrans = 1.0;
-	m_strokeTrans = 1.0;
-	m_fillRule  = true;
-	m_fillMode  = 1;
-	m_lineWidth = 1.0;
-	m_offset    = 0;
-	m_lineEnd   = Qt::SquareCap;
-	m_lineJoin  = Qt::RoundJoin;
-	m_fillGradient   = VGradientEx(VGradientEx::linear);
-	m_strokeGradient = VGradientEx(VGradientEx::linear);
-	// Grayscale conversion parameter
-	m_convertToGray = gray;
-	// Initialization of Windows GDI data
-	m_cr = context;
-	m_positionX = m_positionY = 0;
-	clear();
-}
-
-ScPainterEx_Cairo::~ScPainterEx_Cairo()
-{
-
-}
-
-QColor ScPainterEx_Cairo::transformColor( ScColorShade& colorShade, double trans )
-{
-	QColor c, color;
-	c = ScColorEngine::getShadeColor(colorShade.color, m_doc, colorShade.shade);
-	color = qRgba( qRed(c.rgb()), qGreen(c.rgb()), qBlue(c.rgb()), qAlpha(trans * 255));
-	if ( m_convertToGray )
-	{
-		int grayLevel;
-		QColor grayColor;
-		grayLevel = 0.3 * color.red() + 0.59 * color.green() + 0.11 * color.blue();
-		grayColor = qRgba( grayLevel, grayLevel, grayLevel, qAlpha(color.rgb()));
-		color = grayColor;
-	}
-	return color;
-}
-
-void ScPainterEx_Cairo::transformImage(QImage& image)
-{
-	int rgb, grey;
-	int imageWidth = image.width();
-	int imageHeight = image.height();
-	QRgb *pscan;
-
-	for ( int j = 0; j < imageHeight; j++ )
-	{
-		pscan = (QRgb *) image.scanLine(j);
-		for (int i = 0; i < imageWidth; i++ )
-		{
-			rgb = pscan[i];
-			grey = 0.3 * qRed(rgb) + 0.59 * qGreen(rgb) + 0.11 * qBlue(rgb);
-			pscan[i] = qRgba(grey, grey, grey, qAlpha(rgb));
-		}
-	}
-}
-
-void ScPainterEx_Cairo::begin()
-{
-}
-
-void ScPainterEx_Cairo::end()
-{
-}
-
-void ScPainterEx_Cairo::clear()
-{
-	/*SolidBrush brush( Color(255,255,255) );
-	m_graphics->FillRectangle(&brush, 0, 0, m_width, m_height);*/
-}
-
-void ScPainterEx_Cairo::clear( ScColorShade &c )
-{
-	/*QColor color = transformColor( c, 1.0 );
-	QRgb cs = color.rgb();
-	SolidBrush brush( Color(qAlpha(cs), qRed(cs), qGreen(cs),qBlue(cs)) );
-	m_graphics->FillRectangle(&brush, 0, 0, m_width, m_height);*/
-}
-
-const QTransform ScPainterEx_Cairo::worldMatrix()
-{
-	cairo_matrix_t matrix;
-	cairo_get_matrix(m_cr, &matrix);
-	QTransform mat(matrix.xx, matrix.yx, matrix.xy, matrix.yy, matrix.x0, matrix.y0);
-	return mat;
-}
-
-void ScPainterEx_Cairo::setWorldMatrix( const QTransform &mat )
-{
-	cairo_matrix_t matrix;
-	cairo_matrix_init(&matrix, mat.m11(), mat.m12(), mat.m21(), mat.m22(), mat.dx(), mat.dy());
-	cairo_set_matrix(m_cr, &matrix);
-}
-
-void ScPainterEx_Cairo::translate( double x, double y )
-{
-	cairo_translate(m_cr, x, y);
-}
-
-void ScPainterEx_Cairo::rotate( double r )
-{
-	cairo_rotate(m_cr, r * 3.1415927 / 180.0);
-}
-
-void ScPainterEx_Cairo::scale( double x, double y )
-{
-	cairo_scale(m_cr, x, y);
-}
-
-void ScPainterEx_Cairo::moveTo( const double &x, const double &y )
-{
-	cairo_move_to(m_cr, x, y);
-}
-
-void ScPainterEx_Cairo::lineTo( const double &x, const double &y )
-{
-	cairo_line_to(m_cr, x, y);
-}
-
-void ScPainterEx_Cairo::curveTo( FPoint p1, FPoint p2, FPoint p3 )
-{
-	cairo_curve_to(m_cr, p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y() );
-}
-
-void ScPainterEx_Cairo::newPath()
-{
-	cairo_new_path( m_cr );
-}
-
-void ScPainterEx_Cairo::closePath()
-{
-	cairo_close_path( m_cr);
-}
-
-void ScPainterEx_Cairo::setFillRule( bool fillRule )
-{
-	m_fillRule = fillRule;
-}
-
-void ScPainterEx_Cairo::setFillMode( int fill )
-{
-	m_fillMode = fill;
-}
-
-void ScPainterEx_Cairo::setGradient(VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc)
-{
-	m_fillGradient.setType(mode);
-	m_fillGradient.setOrigin(orig);
-	m_fillGradient.setVector(vec);
-	m_fillGradient.setFocalPoint(foc);
-}
-
-void ScPainterEx_Cairo::setPattern( ScPattern* pattern, QTransform& patternTransform )
-{
-	m_pattern = pattern;
-	m_patternTransform = patternTransform;
-}
-
-void ScPainterEx_Cairo::fillTextPath()
-{
-	drawVPath( 0 );
-}
-
-void ScPainterEx_Cairo::strokeTextPath()
-{
-	if( m_lineWidth == 0 )
-		return;
-	drawVPath( 1 );
-}
-
-void ScPainterEx_Cairo::fillPath()
-{
-	if( m_fillMode != 0)
-		drawVPath( 0 );
-}
-
-void ScPainterEx_Cairo::strokePath()
-{
-	if( m_lineWidth == 0 )
-		return;
-	drawVPath( 1 );
-}
-
-ScColorShade ScPainterEx_Cairo::pen()
-{
-	return m_strokeColor;
-}
-
-ScColorShade ScPainterEx_Cairo::brush()
-{
-	return m_fillColor;
-}
-
-void ScPainterEx_Cairo::setPen( const ScColorShade &c )
-{
-	m_strokeColor = c;
-}
-
-void ScPainterEx_Cairo::setPen( const ScColorShade &c, double w, Qt::PenStyle st, Qt::PenCapStyle ca, Qt::PenJoinStyle jo )
-{
-	m_strokeColor = c;
-	m_lineWidth   = w;
-	m_lineEnd     = ca;
-	m_lineJoin    = jo;
-	m_array.clear();
-	m_offset      = 0;
-	getDashArray(st, w, m_array);
-}
-
-void ScPainterEx_Cairo::setLineWidth( double w )
-{
-	m_lineWidth = w;
-}
-
-void ScPainterEx_Cairo::setPenOpacity( double op )
-{
-	m_strokeTrans = op;
-}
-
-void ScPainterEx_Cairo::setDash(const QVector<double>& array, double ofs)
-{
-	m_array = array;
-	m_offset = ofs;
-}
-
-void ScPainterEx_Cairo::setBrush( const ScColorShade &c )
-{
-	m_fillColor = c;
-}
-
-void ScPainterEx_Cairo::setBrushOpacity( double op )
-{
-	m_fillTrans = op;
-}
-
-void ScPainterEx_Cairo::setOpacity( double op )
-{
-	m_fillTrans = op;
-	m_strokeTrans = op;
-}
-
-void ScPainterEx_Cairo::setFont( const QFont &f)
-{
-	m_font = f;
-}
-
-QFont ScPainterEx_Cairo::font()
-{
-	return m_font;
-}
-
-void ScPainterEx_Cairo::save()
-{
-	cairo_save(m_cr);
-}
-
-void ScPainterEx_Cairo::restore()
-{
-	cairo_restore( m_cr );
-}
-
-void ScPainterEx_Cairo::setRasterOp( int   )
-{
-}
-
-void ScPainterEx_Cairo::drawVPath( int mode )
-{
-	cairo_save( m_cr );
-	if (mode == 0)
-	{
-		if( m_fillRule )
-			cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD);
-		else
-			cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_WINDING);
-		if (m_fillMode == ScPainterExBase::Gradient)
-		{
-			drawGradient( m_fillGradient );
-		}
-		else
-		{
-			double r, g, b;
-			QColor fillColor = transformColor(m_fillColor, 1.0);
-			fillColor.getRgbF(&r, &g, &b);
-			cairo_set_source_rgba( m_cr, r, g, b, m_fillTrans );
-			if (m_fillTrans != 1.0)
-				cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
-			else
-				cairo_set_operator(m_cr, CAIRO_OPERATOR_SOURCE);
-			cairo_fill_preserve( m_cr );
-		}
-	}
-	else
-	{
-		double r, g, b;
-		QColor strokeColor = transformColor( m_strokeColor, 1.0 );
-		strokeColor.getRgbF(&r, &g, &b);
-		cairo_set_source_rgba( m_cr, r, g, b, m_strokeTrans );
-		
-		cairo_set_line_width( m_cr, m_lineWidth );
-		if( m_array.count() > 0 )
-			cairo_set_dash( m_cr, m_array.data(), m_array.count(), static_cast<double>(m_offset));
-		else
-			cairo_set_dash( m_cr, NULL, 0, 0 );
-		if (m_strokeTrans != 1.0)
-			cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
-		else
-			cairo_set_operator(m_cr, CAIRO_OPERATOR_SOURCE);
-		if( m_lineEnd == Qt::RoundCap )
-			cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_ROUND);
-		else if( m_lineEnd == Qt::SquareCap )
-			cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_SQUARE);
-		else if( m_lineEnd == Qt::FlatCap )
-			cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_BUTT);
-		if( m_lineJoin == Qt::RoundJoin )
-			cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_ROUND );
-		else if( m_lineJoin == Qt::BevelJoin )
-			cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_BEVEL );
-		else if( m_lineJoin == Qt::MiterJoin )
-			cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_MITER );
-		cairo_stroke_preserve( m_cr );
-	}
-	cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
-	cairo_restore( m_cr );
-}
-
-void ScPainterEx_Cairo::setClipPath()
-{
-	cairo_clip (m_cr);
-}
-
-void ScPainterEx_Cairo::drawImage( ScImage *image, ScPainterExBase::ImageMode mode )
-{
-	QImage qImage(image->qImage());
-	if (m_convertToGray)
-		transformImage(qImage);
-	cairo_save(m_cr);
-	cairo_set_fill_rule(m_cr, cairo_get_fill_rule(m_cr));
-	cairo_surface_t *image2 = cairo_image_surface_create_for_data ((uchar*)qImage.bits(), CAIRO_FORMAT_ARGB32, qImage.width(), qImage.height(), qImage.width()*4);
-	cairo_set_source_surface (m_cr, image2, 0, 0);
-	cairo_paint_with_alpha (m_cr, m_fillTrans);
-	cairo_surface_destroy (image2);
-	cairo_restore(m_cr);
-}
-
-void ScPainterEx_Cairo::setupPolygon(FPointArray *points, bool closed)
-{
-	bool nPath = true, first = true;
-	FPoint np, np1, np2, np3;
-	if (points->size() > 3)
-	{
-		newPath();
-		for (uint poi=0; poi<points->size()-3; poi += 4)
-		{
-			if (points->point(poi).x() > 900000)
-			{
-				nPath = true;
-				continue;
-			}
-			if (nPath)
-			{
-				np = points->point(poi);
-				if ((!first) && (closed))
-					cairo_close_path( m_cr );
-				moveTo( np.x(), np.y() );
-				nPath = first = false;
-			}
-			np  = points->point(poi);
-			np1 = points->point(poi+1);
-			np2 = points->point(poi+3);
-			np3 = points->point(poi+2);
-			if ((np == np1) && (np2 == np3))
-				lineTo( np3.x(), np3.y() );
-			else
-				curveTo(np1, np2, np3);
-		}
-		if (closed)
-			cairo_close_path( m_cr );
-	}
-}
-
-void ScPainterEx_Cairo::drawPolygon()
-{
-	fillPath();
-}
-
-void ScPainterEx_Cairo::drawPolyLine()
-{
-	strokePath();
-}
-
-void ScPainterEx_Cairo::drawLine(FPoint start, FPoint end)
-{
-	newPath();
-	moveTo(start.x(), start.y());
-	lineTo(end.x(), end.y());
-	strokePath();
-}
-
-void ScPainterEx_Cairo::drawRect(double x, double y, double w, double h)
-{
-	newPath();
-	moveTo( x, y );
-	lineTo( x+w, y );
-	lineTo( x+w, y+h );
-	lineTo( x, y+h );
-	lineTo( x, y );
-	cairo_close_path( m_cr );
-	fillPath();
-	strokePath();
-}
-
-void ScPainterEx_Cairo::drawGradient( VGradientEx& gradient )
-{
-	QRect clipPathRect;
-	save();
-	setClipPath();
-	getClipPathDimensions( clipPathRect );
-	if ( gradient.type() == VGradientEx::linear )
-		drawLinearGradient( gradient, clipPathRect );
-	else if ( gradient.type() == VGradientEx::radial )
-		drawCircularGradient( gradient, clipPathRect );
-	restore();
-}
-
-void ScPainterEx_Cairo::drawLinearGradient( VGradientEx& gradient, const QRect& rect )
-{
-	int index = 0;
-	double r, g, b;
-	QList<VColorStopEx*> colorStops = gradient.colorStops();
-	VColorStopEx* stop = NULL;
-	QColor color;
-
-	if ( gradient.Stops() < 2 )
-		return;
-
-	FPoint p1( gradient.origin().x(), gradient.origin().y() );
-	FPoint p2( gradient.vector().x(), gradient.vector().y() );
-	cairo_pattern_t *pat = cairo_pattern_create_linear (p1.x(), p1.y(), p2.x(), p2.y());	
-
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+
+#include "scpainterex_cairo.h"
+#include "sccolorengine.h"
+#include "util.h"
+#include "util_math.h"
+
+ScPainterEx_Cairo::ScPainterEx_Cairo( cairo_t* context, QRect& rect,  ScribusDoc* doc, bool gray ) : ScPainterExBase()
+{
+	m_doc    = doc;
+	m_width  = rect.width();
+	m_height = rect.height();
+	m_blendModeLayer = 0;
+	m_blendModeFill = 0;
+	m_blendModeStroke = 0;
+	m_strokeColor = ScColorShade( QColor(0,0,0), 100 );
+	m_fillColor = ScColorShade( QColor(0,0,0), 100 );
+	m_fillTrans = 1.0;
+	m_strokeTrans = 1.0;
+	m_fillRule  = true;
+	m_fillMode  = 1;
+	m_lineWidth = 1.0;
+	m_offset    = 0;
+	m_lineEnd   = Qt::SquareCap;
+	m_lineJoin  = Qt::RoundJoin;
+	m_fillGradient   = VGradientEx(VGradientEx::linear);
+	m_strokeGradient = VGradientEx(VGradientEx::linear);
+	// Grayscale conversion parameter
+	m_convertToGray = gray;
+	// Initialization of Windows GDI data
+	m_cr = context;
+	m_positionX = m_positionY = 0;
+	clear();
+}
+
+ScPainterEx_Cairo::~ScPainterEx_Cairo()
+{
+
+}
+
+QColor ScPainterEx_Cairo::transformColor( ScColorShade& colorShade, double trans )
+{
+	QColor c, color;
+	c = ScColorEngine::getShadeColor(colorShade.color, m_doc, colorShade.shade);
+	color = qRgba( qRed(c.rgb()), qGreen(c.rgb()), qBlue(c.rgb()), qAlpha(trans * 255));
+	if ( m_convertToGray )
+	{
+		int grayLevel;
+		QColor grayColor;
+		grayLevel = 0.3 * color.red() + 0.59 * color.green() + 0.11 * color.blue();
+		grayColor = qRgba( grayLevel, grayLevel, grayLevel, qAlpha(color.rgb()));
+		color = grayColor;
+	}
+	return color;
+}
+
+void ScPainterEx_Cairo::transformImage(QImage& image)
+{
+	int rgb, grey;
+	int imageWidth = image.width();
+	int imageHeight = image.height();
+	QRgb *pscan;
+
+	for ( int j = 0; j < imageHeight; j++ )
+	{
+		pscan = (QRgb *) image.scanLine(j);
+		for (int i = 0; i < imageWidth; i++ )
+		{
+			rgb = pscan[i];
+			grey = 0.3 * qRed(rgb) + 0.59 * qGreen(rgb) + 0.11 * qBlue(rgb);
+			pscan[i] = qRgba(grey, grey, grey, qAlpha(rgb));
+		}
+	}
+}
+
+void ScPainterEx_Cairo::begin()
+{
+}
+
+void ScPainterEx_Cairo::end()
+{
+}
+
+void ScPainterEx_Cairo::clear()
+{
+	/*SolidBrush brush( Color(255,255,255) );
+	m_graphics->FillRectangle(&brush, 0, 0, m_width, m_height);*/
+}
+
+void ScPainterEx_Cairo::clear( ScColorShade &c )
+{
+	/*QColor color = transformColor( c, 1.0 );
+	QRgb cs = color.rgb();
+	SolidBrush brush( Color(qAlpha(cs), qRed(cs), qGreen(cs),qBlue(cs)) );
+	m_graphics->FillRectangle(&brush, 0, 0, m_width, m_height);*/
+}
+
+const QTransform ScPainterEx_Cairo::worldMatrix()
+{
+	cairo_matrix_t matrix;
+	cairo_get_matrix(m_cr, &matrix);
+	QTransform mat(matrix.xx, matrix.yx, matrix.xy, matrix.yy, matrix.x0, matrix.y0);
+	return mat;
+}
+
+void ScPainterEx_Cairo::setWorldMatrix( const QTransform &mat )
+{
+	cairo_matrix_t matrix;
+	cairo_matrix_init(&matrix, mat.m11(), mat.m12(), mat.m21(), mat.m22(), mat.dx(), mat.dy());
+	cairo_set_matrix(m_cr, &matrix);
+}
+
+void ScPainterEx_Cairo::translate( double x, double y )
+{
+	cairo_translate(m_cr, x, y);
+}
+
+void ScPainterEx_Cairo::rotate( double r )
+{
+	cairo_rotate(m_cr, r * 3.1415927 / 180.0);
+}
+
+void ScPainterEx_Cairo::scale( double x, double y )
+{
+	cairo_scale(m_cr, x, y);
+}
+
+void ScPainterEx_Cairo::moveTo( const double &x, const double &y )
+{
+	cairo_move_to(m_cr, x, y);
+}
+
+void ScPainterEx_Cairo::lineTo( const double &x, const double &y )
+{
+	cairo_line_to(m_cr, x, y);
+}
+
+void ScPainterEx_Cairo::curveTo( FPoint p1, FPoint p2, FPoint p3 )
+{
+	cairo_curve_to(m_cr, p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y() );
+}
+
+void ScPainterEx_Cairo::newPath()
+{
+	cairo_new_path( m_cr );
+}
+
+void ScPainterEx_Cairo::closePath()
+{
+	cairo_close_path( m_cr);
+}
+
+void ScPainterEx_Cairo::setFillRule( bool fillRule )
+{
+	m_fillRule = fillRule;
+}
+
+void ScPainterEx_Cairo::setFillMode( int fill )
+{
+	m_fillMode = fill;
+}
+
+void ScPainterEx_Cairo::setStrokeMode( int stroke )
+{
+	m_strokeMode = stroke;
+}
+
+void ScPainterEx_Cairo::setGradient(VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew)
+{
+	m_fillGradient.setType(mode);
+	m_fillGradient.setOrigin(orig);
+	m_fillGradient.setVector(vec);
+	m_fillGradient.setFocalPoint(foc);
+
+	m_strokeGradient.setType(mode);
+	m_strokeGradient.setOrigin(orig);
+	m_strokeGradient.setVector(vec);
+	m_strokeGradient.setFocalPoint(foc);
+
+	m_gradientScale = scale;
+	if (skew == 90)
+		m_gradientSkew = 1;
+	else if (skew == 180)
+		m_gradientSkew = 0;
+	else if (skew == 270)
+		m_gradientSkew = -1;
+	else if (skew == 360)
+		m_gradientSkew = 0;
+	else
+		m_gradientSkew = tan(M_PI / 180.0 * skew);
+}
+
+void ScPainterEx_Cairo::setMaskMode(int mask)
+{
+	m_maskMode = mask;
+}
+
+void ScPainterEx_Cairo::setGradientMask(VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew)
+{
+	m_maskGradient.setType(mode);
+	m_maskGradient.setOrigin(orig);
+	m_maskGradient.setVector(vec);
+	m_maskGradient.setFocalPoint(foc);
+	m_maskGradientScale = scale;
+	if (skew == 90)
+		m_maskGradientSkew = 1;
+	else if (skew == 180)
+		m_maskGradientSkew = 0;
+	else if (skew == 270)
+		m_maskGradientSkew = -1;
+	else if (skew == 360)
+		m_maskGradientSkew = 0;
+	else
+		m_maskGradientSkew = tan(M_PI / 180.0 * skew);
+}
+
+void ScPainterEx_Cairo::setPatternMask(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY)
+{
+	m_maskPattern = pattern;
+	m_maskPatternScaleX = scaleX / 100.0;
+	m_maskPatternScaleY = scaleY / 100.0;
+	m_maskPatternOffsetX = offsetX;
+	m_maskPatternOffsetY = offsetY;
+	m_maskPatternRotation = rotation;
+	m_maskPatternSkewX = skewX;
+	m_maskPatternSkewY = skewY;
+	m_maskPatternMirrorX = mirrorX;
+	m_maskPatternMirrorY = mirrorY;
+}
+
+void ScPainterEx_Cairo::setPattern(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY)
+{
+	m_pattern = pattern;
+	m_patternScaleX = scaleX / 100.0;
+	m_patternScaleY = scaleY / 100.0;
+	m_patternOffsetX = offsetX;
+	m_patternOffsetY = offsetY;
+	m_patternRotation = rotation;
+	m_patternSkewX   = skewX;
+	m_patternSkewY   = skewY;
+	m_patternMirrorX = mirrorX;
+	m_patternMirrorY = mirrorY;
+}
+
+void ScPainterEx_Cairo::set4ColorGeometry(FPoint p1, FPoint p2, FPoint p3, FPoint p4, FPoint c1, FPoint c2, FPoint c3, FPoint c4)
+{
+	m_fillGradient.setType(VGradientEx::fourcolor);
+	m_gradPatchP1 = p1;
+	m_gradPatchP2 = p2;
+	m_gradPatchP3 = p3;
+	m_gradPatchP4 = p4;
+	m_gradControlP1 = c1;
+	m_gradControlP2 = c2;
+	m_gradControlP3 = c3;
+	m_gradControlP4 = c4;
+}
+
+void ScPainterEx_Cairo::set4ColorColors(const ScColorShade&  col1, const ScColorShade&  col2, const ScColorShade&  col3, const ScColorShade&  col4)
+{
+	m_gradPatchColor1 = col1;
+	m_gradPatchColor2 = col2;
+	m_gradPatchColor3 = col3;
+	m_gradPatchColor4 = col4;
+}
+
+void ScPainterEx_Cairo::setDiamondGeometry(FPoint p1, FPoint p2, FPoint p3, FPoint p4, FPoint c1, FPoint c2, FPoint c3, FPoint c4, FPoint c5)
+{
+	m_fillGradient.setType(VGradientEx::diamond);
+	m_gradPatchP1 = p1;
+	m_gradPatchP2 = p2;
+	m_gradPatchP3 = p3;
+	m_gradPatchP4 = p4;
+	m_gradControlP1 = c1;
+	m_gradControlP2 = c2;
+	m_gradControlP3 = c3;
+	m_gradControlP4 = c4;
+	m_gradControlP5 = c5;
+}
+
+void ScPainterEx_Cairo::setMeshGradient(FPoint p1, FPoint p2, FPoint p3, FPoint p4, QList<QList<meshPoint> > meshArray)
+{
+	m_fillGradient.setType(VGradientEx::mesh);
+	m_meshGradientArray = meshArray;
+	m_gradPatchP1 = p1;
+	m_gradPatchP2 = p2;
+	m_gradPatchP3 = p3;
+	m_gradPatchP4 = p4;
+}
+
+void ScPainterEx_Cairo::setMeshGradient(FPoint p1, FPoint p2, FPoint p3, FPoint p4, QList<meshGradientPatch> meshPatches)
+{
+	m_fillGradient.setType(VGradientEx::freemesh);
+	m_meshGradientPatches = meshPatches;
+	m_gradPatchP1 = p1;
+	m_gradPatchP2 = p2;
+	m_gradPatchP3 = p3;
+	m_gradPatchP4 = p4;
+}
+
+void ScPainterEx_Cairo::fillTextPath()
+{
+	drawVPath( 0 );
+}
+
+void ScPainterEx_Cairo::strokeTextPath()
+{
+	if( m_lineWidth == 0 )
+		return;
+	drawVPath( 1 );
+}
+
+void ScPainterEx_Cairo::fillPath()
+{
+	if( m_fillMode != 0)
+		drawVPath( 0 );
+}
+
+void ScPainterEx_Cairo::strokePath()
+{
+	if( m_lineWidth == 0 )
+		return;
+	drawVPath( 1 );
+}
+
+ScColorShade ScPainterEx_Cairo::pen()
+{
+	return m_strokeColor;
+}
+
+ScColorShade ScPainterEx_Cairo::brush()
+{
+	return m_fillColor;
+}
+
+void ScPainterEx_Cairo::setPen( const ScColorShade &c )
+{
+	m_strokeColor = c;
+}
+
+void ScPainterEx_Cairo::setPen( const ScColorShade &c, double w, Qt::PenStyle st, Qt::PenCapStyle ca, Qt::PenJoinStyle jo )
+{
+	m_strokeColor = c;
+	m_lineWidth   = w;
+	m_lineEnd     = ca;
+	m_lineJoin    = jo;
+	m_array.clear();
+	m_offset      = 0;
+	getDashArray(st, w, m_array);
+}
+
+void ScPainterEx_Cairo::setLineWidth( double w )
+{
+	m_lineWidth = w;
+}
+
+void ScPainterEx_Cairo::setPenOpacity( double op )
+{
+	m_strokeTrans = op;
+}
+
+void ScPainterEx_Cairo::setDash(const QVector<double>& array, double ofs)
+{
+	m_array = array;
+	m_offset = ofs;
+}
+
+void ScPainterEx_Cairo::setBrush( const ScColorShade &c )
+{
+	m_fillColor = c;
+}
+
+void ScPainterEx_Cairo::setBrushOpacity( double op )
+{
+	m_fillTrans = op;
+}
+
+void ScPainterEx_Cairo::setOpacity( double op )
+{
+	m_fillTrans = op;
+	m_strokeTrans = op;
+}
+
+void ScPainterEx_Cairo::setFont( const QFont &f)
+{
+	m_font = f;
+}
+
+QFont ScPainterEx_Cairo::font()
+{
+	return m_font;
+}
+
+void ScPainterEx_Cairo::save()
+{
+	cairo_save(m_cr);
+}
+
+void ScPainterEx_Cairo::restore()
+{
+	cairo_restore( m_cr );
+}
+
+void ScPainterEx_Cairo::setRasterOp(int blendMode)
+{
+	if (blendMode == 0)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
+	else if (blendMode == 1)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_DARKEN);
+	else if (blendMode == 2)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_LIGHTEN);
+	else if (blendMode == 3)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_MULTIPLY);
+	else if (blendMode == 4)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_SCREEN);
+	else if (blendMode == 5)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_OVERLAY);
+	else if (blendMode == 6)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_HARD_LIGHT);
+	else if (blendMode == 7)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_SOFT_LIGHT);
+	else if (blendMode == 8)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_DIFFERENCE);
+	else if (blendMode == 9)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_EXCLUSION);
+	else if (blendMode == 10)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_COLOR_DODGE);
+	else if (blendMode == 11)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_COLOR_BURN);
+	else if (blendMode == 12)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_HSL_HUE);
+	else if (blendMode == 13)
+		cairo_set_operator(m_cr, CAIRO_OPERATOR_HSL_SATURATION);
+	else if (blendMode == 14)
+		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);
+}
+
+void ScPainterEx_Cairo::setBlendModeFill( int blendMode )
+{
+	m_blendModeFill = blendMode;
+}
+
+void ScPainterEx_Cairo::setBlendModeStroke( int blendMode )
+{
+	m_blendModeStroke = blendMode;
+}
+
+void ScPainterEx_Cairo::drawVPath( int mode )
+{
+	cairo_save( m_cr );
+	if (mode == 0)
+	{
+		if( m_fillRule )
+			cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD);
+		else
+			cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_WINDING);
+		if (m_fillMode == ScPainterExBase::Solid)
+		{
+			double r, g, b;
+			QColor fillColor = transformColor(m_fillColor, 1.0);
+			fillColor.getRgbF(&r, &g, &b);
+			if (m_maskMode > 0)
+			{
+				/*cairo_pattern_t *pat = getMaskPattern();
+				cairo_set_source_rgb( m_cr, r, g, b );
+				setRasterOp(m_blendModeFill);
+				cairo_clip_preserve(m_cr);
+				cairo_mask(m_cr, pat);
+				if ((maskMode == 2) || (maskMode == 4) || (maskMode == 5) || (maskMode == 6))
+					cairo_surface_destroy(imageMask);
+				cairo_pattern_destroy(pat);*/
+			}
+			else
+			{
+				cairo_set_source_rgba(m_cr, r, g, b, m_fillTrans);
+				setRasterOp(m_blendModeFill);
+				cairo_fill_preserve(m_cr);
+			}
+		}
+		else if (m_fillMode == ScPainterExBase::Gradient)
+		{
+			drawGradient( m_fillGradient );
+		}
+		else if (m_fillMode == ScPainterExBase::Pattern)
+		{
+
+		}
+	}
+	else
+	{
+		double r, g, b;
+		QColor strokeColor = transformColor( m_strokeColor, 1.0 );
+		strokeColor.getRgbF(&r, &g, &b);
+		cairo_set_source_rgba( m_cr, r, g, b, m_strokeTrans );
+		
+		cairo_set_line_width( m_cr, m_lineWidth );
+		if( m_array.count() > 0 )
+			cairo_set_dash( m_cr, m_array.data(), m_array.count(), static_cast<double>(m_offset));
+		else
+			cairo_set_dash( m_cr, NULL, 0, 0 );
+		if (m_strokeTrans != 1.0)
+			cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
+		else
+			cairo_set_operator(m_cr, CAIRO_OPERATOR_SOURCE);
+		if( m_lineEnd == Qt::RoundCap )
+			cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_ROUND);
+		else if( m_lineEnd == Qt::SquareCap )
+			cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_SQUARE);
+		else if( m_lineEnd == Qt::FlatCap )
+			cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_BUTT);
+		if( m_lineJoin == Qt::RoundJoin )
+			cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_ROUND );
+		else if( m_lineJoin == Qt::BevelJoin )
+			cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_BEVEL );
+		else if( m_lineJoin == Qt::MiterJoin )
+			cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_MITER );
+		cairo_stroke_preserve( m_cr );
+	}
+	cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
+	cairo_restore( m_cr );
+}
+
+void ScPainterEx_Cairo::setClipPath()
+{
+	cairo_clip (m_cr);
+}
+
+void ScPainterEx_Cairo::drawImage( ScImage *image, ScPainterExBase::ImageMode mode )
+{
+	QImage qImage(image->qImage());
+	if (m_convertToGray)
+		transformImage(qImage);
+	cairo_save(m_cr);
+	cairo_set_fill_rule(m_cr, cairo_get_fill_rule(m_cr));
+	cairo_surface_t *image2 = cairo_image_surface_create_for_data ((uchar*)qImage.bits(), CAIRO_FORMAT_ARGB32, qImage.width(), qImage.height(), qImage.width()*4);
+	cairo_set_source_surface (m_cr, image2, 0, 0);
+	cairo_paint_with_alpha (m_cr, m_fillTrans);
+	cairo_surface_destroy (image2);
+	cairo_restore(m_cr);
+}
+
+void ScPainterEx_Cairo::setupPolygon(FPointArray *points, bool closed)
+{
+	bool nPath = true, first = true;
+	FPoint np, np1, np2, np3;
+	if (points->size() > 3)
+	{
+		newPath();
+		for (uint poi=0; poi<points->size()-3; poi += 4)
+		{
+			if (points->point(poi).x() > 900000)
+			{
+				nPath = true;
+				continue;
+			}
+			if (nPath)
+			{
+				np = points->point(poi);
+				if ((!first) && (closed))
+					cairo_close_path( m_cr );
+				moveTo( np.x(), np.y() );
+				nPath = first = false;
+			}
+			np  = points->point(poi);
+			np1 = points->point(poi+1);
+			np2 = points->point(poi+3);
+			np3 = points->point(poi+2);
+			if ((np == np1) && (np2 == np3))
+				lineTo( np3.x(), np3.y() );
+			else
+				curveTo(np1, np2, np3);
+		}
+		if (closed)
+			cairo_close_path( m_cr );
+	}
+}
+
+void ScPainterEx_Cairo::drawPolygon()
+{
+	fillPath();
+}
+
+void ScPainterEx_Cairo::drawPolyLine()
+{
+	strokePath();
+}
+
+void ScPainterEx_Cairo::drawLine(FPoint start, FPoint end)
+{
+	newPath();
+	moveTo(start.x(), start.y());
+	lineTo(end.x(), end.y());
+	strokePath();
+}
+
+void ScPainterEx_Cairo::drawRect(double x, double y, double w, double h)
+{
+	newPath();
+	moveTo( x, y );
+	lineTo( x+w, y );
+	lineTo( x+w, y+h );
+	lineTo( x, y+h );
+	lineTo( x, y );
+	cairo_close_path( m_cr );
+	fillPath();
+	strokePath();
+}
+
+void ScPainterEx_Cairo::drawGradient( VGradientEx& gradient )
+{
+	QRect clipPathRect;
+	save();
+	setClipPath();
+	getClipPathDimensions( clipPathRect );
+	if ( gradient.type() == VGradientEx::linear )
+		drawLinearGradient( gradient, clipPathRect );
+	else if ( gradient.type() == VGradientEx::radial )
+		drawCircularGradient( gradient, clipPathRect );
+	else if ( gradient.type() == VGradientEx::fourcolor )
+		drawFourColorGradient( clipPathRect );
+	else if ( gradient.type() == VGradientEx::diamond )
+		drawDiamondGradient( gradient, clipPathRect );
+	else if ( gradient.type() == VGradientEx::mesh )
+		drawMeshGradient( clipPathRect );
+	else if ( gradient.type() == VGradientEx::freemesh )
+		drawFreeMeshGradient( clipPathRect );
+	restore();
+}
+
+void ScPainterEx_Cairo::drawLinearGradient( VGradientEx& gradient, const QRect& rect )
+{
+	int index = 0;
+	double r, g, b;
+	QList<VColorStopEx*> colorStops = gradient.colorStops();
+	VColorStopEx* stop = NULL;
+	QColor color;
+
+	if ( gradient.Stops() < 2 )
+		return;
+
+	FPoint p1( gradient.origin().x(), gradient.origin().y() );
+	FPoint p2( gradient.vector().x(), gradient.vector().y() );
+	cairo_pattern_t *pat = cairo_pattern_create_linear (p1.x(), p1.y(), p2.x(), p2.y());	
+
 	bool   isFirst  = true;
-	double lastStop = 0.0;
-	for( uint index = 0 ; index < gradient.Stops(); index++)
-	{
-		stop  = colorStops.at(index);
+	double lastStop = 0.0;
+	for( uint index = 0 ; index < gradient.Stops(); index++)
+	{
+		stop  = colorStops.at(index);
 		if ((lastStop == stop->rampPoint) && (!isFirst))
 			continue;
-		isFirst = false;
-		color = transformColor( ScColorShade(stop->color, stop->shade), 1.0 );
-		color.getRgbF(&r, &g, &b);
-		cairo_pattern_add_color_stop_rgba (pat, stop->rampPoint, r, g, b, stop->opacity);
-		lastStop = stop->rampPoint;
-	}
-
-	cairo_set_source (m_cr, pat);
-	//cairo_clip_preserve (m_cr);
-	cairo_paint_with_alpha (m_cr, m_fillTrans);
-	cairo_pattern_destroy (pat);
-}
-
-void ScPainterEx_Cairo::drawCircularGradient( VGradientEx& gradient, const QRect& rect )
-{
-	int offset = 0;
-	double r, g, b;
-	QList<VColorStopEx*> colorStops = gradient.colorStops();
-	VColorStopEx* stop = NULL;
-	QColor color;
-
-	FPoint pc( gradient.origin().x(), gradient.origin().y() );
-	FPoint pf( gradient.focalPoint().x(), gradient.focalPoint().y() );
-	FPoint pv( gradient.vector().x(), gradient.vector().y() );
-	double rad = sqrt( pow(pv.x() - pc.x(), 2) + pow(pv.y() - pc.y(), 2) );
-
-	cairo_pattern_t* pat = cairo_pattern_create_radial (pc.x(), pc.y(), 0.1, pc.x(), pc.y(), rad);	
-
+		isFirst = false;
+		color = transformColor( ScColorShade(stop->color, stop->shade), 1.0 );
+		color.getRgbF(&r, &g, &b);
+		cairo_pattern_add_color_stop_rgba (pat, stop->rampPoint, r, g, b, stop->opacity);
+		lastStop = stop->rampPoint;
+	}
+
+	cairo_set_source (m_cr, pat);
+	//cairo_clip_preserve (m_cr);
+	cairo_paint_with_alpha (m_cr, m_fillTrans);
+	cairo_pattern_destroy (pat);
+}
+
+void ScPainterEx_Cairo::drawCircularGradient( VGradientEx& gradient, const QRect& rect )
+{
+	int offset = 0;
+	double r, g, b;
+	QList<VColorStopEx*> colorStops = gradient.colorStops();
+	VColorStopEx* stop = NULL;
+	QColor color;
+
+	FPoint pc( gradient.origin().x(), gradient.origin().y() );
+	FPoint pf( gradient.focalPoint().x(), gradient.focalPoint().y() );
+	FPoint pv( gradient.vector().x(), gradient.vector().y() );
+	double rad = sqrt( pow(pv.x() - pc.x(), 2) + pow(pv.y() - pc.y(), 2) );
+
+	cairo_pattern_t* pat = cairo_pattern_create_radial (pc.x(), pc.y(), 0.1, pc.x(), pc.y(), rad);	
+
 	bool   isFirst  = true;
-	double lastStop = 0.0;
-	for( uint index = 0 ; index < gradient.Stops() ; index++)
-	{
-		stop  = colorStops.at(index);
+	double lastStop = 0.0;
+	for( uint index = 0 ; index < gradient.Stops() ; index++)
+	{
+		stop  = colorStops.at(index);
 		if ((lastStop == stop->rampPoint) && (!isFirst))
 			continue;
-		isFirst = false;
-		color = transformColor( ScColorShade(stop->color, stop->shade), 1.0 );
-		color.getRgbF(&r, &g, &b);
-		cairo_pattern_add_color_stop_rgba (pat, stop->rampPoint, r, g, b, stop->opacity);
-		lastStop = stop->rampPoint;
-	}
-	
-	cairo_set_source (m_cr, pat);
-	//cairo_clip_preserve (m_cr);
-	cairo_paint_with_alpha (m_cr, m_fillTrans);
-	cairo_pattern_destroy (pat);
-}
-
-void ScPainterEx_Cairo::getClipPathDimensions( QRect& r )
-{
-	double left = 0.0, right = 0.0, bottom = 0.0, top = 0.0;
-	cairo_clip_extents(m_cr, &left, &bottom, &right, &top);
-	r.setLeft( left );
-	r.setRight( right );
-	r.setBottom( bottom );
-	r.setTop( top );
-}
+		isFirst = false;
+		color = transformColor( ScColorShade(stop->color, stop->shade), 1.0 );
+		color.getRgbF(&r, &g, &b);
+		cairo_pattern_add_color_stop_rgba (pat, stop->rampPoint, r, g, b, stop->opacity);
+		lastStop = stop->rampPoint;
+	}
+	
+	cairo_set_source (m_cr, pat);
+	//cairo_clip_preserve (m_cr);
+	cairo_paint_with_alpha (m_cr, m_fillTrans);
+	cairo_pattern_destroy (pat);
+}
+
+void ScPainterEx_Cairo::drawFourColorGradient( const QRect& rect )
+{
+	cairo_pattern_t *pat = NULL;
+	cairo_surface_t *img = NULL;
+	cairo_t *cr = NULL;
+	cairo_pattern_t *mpat = NULL;
+	QColor color;
+
+	double p1x = m_gradPatchP1.x();
+	double p1y = m_gradPatchP1.y();
+	double p2x = m_gradPatchP2.x();
+	double p2y = m_gradPatchP2.y();
+	double p3x = m_gradPatchP3.x();
+	double p3y = m_gradPatchP3.y();
+	double p4x = m_gradPatchP4.x();
+	double p4y = m_gradPatchP4.y();
+	img = cairo_surface_create_similar(cairo_get_target(m_cr), CAIRO_CONTENT_COLOR_ALPHA, p3x, p3y);
+	cr = cairo_create(img);
+	cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
+	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+	cairo_set_tolerance(cr, 0.5 );
+	double r, g, b, a;
+	mpat = cairo_pattern_create_mesh();
+	cairo_pattern_mesh_begin_patch(mpat);
+	cairo_pattern_mesh_move_to(mpat, p1x, p1y);
+	cairo_pattern_mesh_line_to(mpat, p2x, p2y);
+	cairo_pattern_mesh_line_to(mpat, p3x, p3y);
+	cairo_pattern_mesh_line_to(mpat, p4x, p4y);
+	cairo_pattern_mesh_line_to(mpat, p1x, p1y);
+	cairo_pattern_mesh_set_control_point(mpat, 0, m_gradControlP1.x(),  m_gradControlP1.y());
+	cairo_pattern_mesh_set_control_point(mpat, 1, m_gradControlP2.x(),  m_gradControlP2.y());
+	cairo_pattern_mesh_set_control_point(mpat, 2, m_gradControlP3.x(),  m_gradControlP3.y());
+	cairo_pattern_mesh_set_control_point(mpat, 3, m_gradControlP4.x(),  m_gradControlP4.y());
+	color = transformColor(m_gradPatchColor1, 1.0);
+	color.getRgbF(&r, &g, &b, &a);
+	cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
+	color = transformColor(m_gradPatchColor2, 1.0);
+	color.getRgbF(&r, &g, &b, &a);
+	cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
+	color = transformColor(m_gradPatchColor3, 1.0);
+	color.getRgbF(&r, &g, &b, &a);
+	cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
+	color = transformColor(m_gradPatchColor4, 1.0);
+	color.getRgbF(&r, &g, &b, &a);
+	cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
+	cairo_pattern_mesh_end_patch(mpat);
+	cairo_pattern_set_filter(mpat, CAIRO_FILTER_GOOD);
+	cairo_set_source(cr, mpat);
+	cairo_paint_with_alpha(cr, 1.0);
+	pat = cairo_pattern_create_for_surface(img);
+	cairo_pattern_set_extend(pat, CAIRO_EXTEND_NONE);
+	cairo_pattern_set_filter(pat, CAIRO_FILTER_GOOD);
+
+	cairo_set_source (m_cr, pat);
+	cairo_clip_preserve (m_cr);
+
+	if (m_maskMode > 0)
+	{
+		/*cairo_pattern_t *patM = getMaskPattern();
+		setRasterOp(m_blendModeFill);
+		cairo_mask(m_cr, patM);
+		if ((m_maskMode == 2) || (m_maskMode == 4) || (m_maskMode == 5) || (m_maskMode == 6))
+			cairo_surface_destroy(imageMask);
+		cairo_pattern_destroy (patM);*/
+	}
+	else
+	{
+		setRasterOp(m_blendModeFill);
+		cairo_paint_with_alpha (m_cr, m_fillTrans);
+	}
+	cairo_pattern_destroy (pat);
+
+	if (img) cairo_surface_destroy(img);
+	if (mpat) cairo_pattern_destroy(mpat);
+	if (cr) cairo_destroy( cr );
+}
+
+void ScPainterEx_Cairo::drawDiamondGradient( VGradientEx& gradient, const QRect& rect )
+{
+	cairo_pattern_t *pat = NULL;
+	cairo_surface_t *img = NULL;
+	cairo_t *cr = NULL;
+	cairo_pattern_t *mpat = NULL;
+	VColorStopEx* stop = NULL;
+	QColor color;
+
+	double p1x = m_gradControlP1.x();
+	double p1y = m_gradControlP1.y();
+	double p2x = m_gradControlP2.x();
+	double p2y = m_gradControlP2.y();
+	double p3x = m_gradControlP3.x();
+	double p3y = m_gradControlP3.y();
+	double p4x = m_gradControlP4.x();
+	double p4y = m_gradControlP4.y();
+	img = cairo_surface_create_similar(cairo_get_target(m_cr), CAIRO_CONTENT_COLOR_ALPHA, m_gradPatchP3.x(), m_gradPatchP3.y());
+	cr = cairo_create(img);
+	cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
+	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+	cairo_set_tolerance(cr, 0.5 );
+	double r, g, b, a;
+	QList<VColorStopEx*> colorStops = gradient.colorStops();
+	QList<QColor> qStopColors;
+	QColor qStopColor;
+	for( int offset = 0 ; offset < colorStops.count() ; offset++ )
+	{
+		stop = colorStops.at(offset);
+		qStopColor = transformColor( ScColorShade(stop->color, stop->shade), 1.0);
+		int h, s, v, sneu, vneu;
+		int shad = stop->shade;
+		qStopColor.getHsv(&h, &s, &v);
+		sneu = s * shad / 100;
+		vneu = 255 - ((255 - v) * shad / 100);
+		qStopColor.setHsv(h, sneu, vneu);
+		qStopColor.setAlphaF(colorStops[offset]->opacity);
+		qStopColors.append(qStopColor);
+	}
+	qStopColors[qStopColors.count()-1].getRgbF(&r, &g, &b, &a);
+	QPointF centerP = QPointF(m_gradControlP5.x(), m_gradControlP5.y());
+	QLineF edge1 = QLineF(centerP, QPointF(p1x, p1y));
+	QLineF edge2 = QLineF(centerP, QPointF(p2x, p2y));
+	QLineF edge3 = QLineF(centerP, QPointF(p3x, p3y));
+	QLineF edge4 = QLineF(centerP, QPointF(p4x, p4y));
+	QPointF p1 = edge1.pointAt(colorStops[colorStops.count() - 1]->rampPoint);
+	QPointF p2 = edge2.pointAt(colorStops[colorStops.count() - 1]->rampPoint);
+	QPointF p3 = edge3.pointAt(colorStops[colorStops.count() - 1]->rampPoint);
+	QPointF p4 = edge4.pointAt(colorStops[colorStops.count() - 1]->rampPoint);
+	cairo_set_source_rgba(cr, r, g, b, a);
+	cairo_paint_with_alpha(cr, 1.0);
+	cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OUT);
+	cairo_new_path(cr);
+	cairo_move_to(cr, p1.x(), p1.y());
+	cairo_line_to(cr, p2.x(), p2.y());
+	cairo_line_to(cr, p3.x(), p3.y());
+	cairo_line_to(cr, p4.x(), p4.y());
+	cairo_close_path(cr);
+	cairo_set_source_rgba(cr, 0, 0, 0, 1);
+	cairo_fill(cr);
+	cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
+	mpat = cairo_pattern_create_mesh();
+	for( int offset = 1 ; offset < colorStops.count() ; offset++ )
+	{
+		QLineF e1 = edge1;
+		QLineF e1s = edge1;
+		QLineF e2 = edge2;
+		QLineF e2s = edge2;
+		QLineF e3 = edge3;
+		QLineF e3s = edge3;
+		QLineF e4 = edge4;
+		QLineF e4s = edge4;
+		e1.setLength(edge1.length() * colorStops[ offset ]->rampPoint);
+		e2.setLength(edge2.length() * colorStops[ offset ]->rampPoint);
+		e3.setLength(edge3.length() * colorStops[ offset ]->rampPoint);
+		e4.setLength(edge4.length() * colorStops[ offset ]->rampPoint);
+		e1s.setLength(edge1.length() * colorStops[ offset - 1 ]->rampPoint);
+		e2s.setLength(edge2.length() * colorStops[ offset - 1 ]->rampPoint);
+		e3s.setLength(edge3.length() * colorStops[ offset - 1 ]->rampPoint);
+		e4s.setLength(edge4.length() * colorStops[ offset - 1 ]->rampPoint);
+		if (offset == 1)
+		{
+			cairo_pattern_mesh_begin_patch(mpat);
+			cairo_pattern_mesh_move_to(mpat, centerP.x(), centerP.y());
+			cairo_pattern_mesh_line_to(mpat, e1.x2(), e1.y2());
+			cairo_pattern_mesh_line_to(mpat, e2.x2(), e2.y2());
+			cairo_pattern_mesh_line_to(mpat, centerP.x(), centerP.y());
+			qStopColors[0].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
+			qStopColors[1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
+			cairo_pattern_mesh_end_patch(mpat);
+			cairo_pattern_mesh_begin_patch(mpat);
+			cairo_pattern_mesh_move_to(mpat, centerP.x(), centerP.y());
+			cairo_pattern_mesh_line_to(mpat, e2.x2(), e2.y2());
+			cairo_pattern_mesh_line_to(mpat, e3.x2(), e3.y2());
+			cairo_pattern_mesh_line_to(mpat, centerP.x(), centerP.y());
+			qStopColors[0].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
+			qStopColors[1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
+			cairo_pattern_mesh_end_patch(mpat);
+			cairo_pattern_mesh_begin_patch(mpat);
+			cairo_pattern_mesh_move_to(mpat, centerP.x(), centerP.y());
+			cairo_pattern_mesh_line_to(mpat, e3.x2(), e3.y2());
+			cairo_pattern_mesh_line_to(mpat, e4.x2(), e4.y2());
+			cairo_pattern_mesh_line_to(mpat, centerP.x(), centerP.y());
+			qStopColors[0].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
+			qStopColors[1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
+			cairo_pattern_mesh_end_patch(mpat);
+			cairo_pattern_mesh_begin_patch(mpat);
+			cairo_pattern_mesh_move_to(mpat, centerP.x(), centerP.y());
+			cairo_pattern_mesh_line_to(mpat, e4.x2(), e4.y2());
+			cairo_pattern_mesh_line_to(mpat, e1.x2(), e1.y2());
+			cairo_pattern_mesh_line_to(mpat, centerP.x(), centerP.y());
+			qStopColors[0].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
+			qStopColors[1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
+			cairo_pattern_mesh_end_patch(mpat);
+		}
+		else
+		{
+			cairo_pattern_mesh_begin_patch(mpat);
+			cairo_pattern_mesh_move_to(mpat, e1s.x2(), e1s.y2());
+			cairo_pattern_mesh_line_to(mpat, e1.x2(), e1.y2());
+			cairo_pattern_mesh_line_to(mpat, e2.x2(), e2.y2());
+			cairo_pattern_mesh_line_to(mpat, e2s.x2(), e2s.y2());
+			qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
+			qStopColors[offset].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
+			qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
+			cairo_pattern_mesh_end_patch(mpat);
+			cairo_pattern_mesh_begin_patch(mpat);
+			cairo_pattern_mesh_move_to(mpat, e2s.x2(), e2s.y2());
+			cairo_pattern_mesh_line_to(mpat, e2.x2(), e2.y2());
+			cairo_pattern_mesh_line_to(mpat, e3.x2(), e3.y2());
+			cairo_pattern_mesh_line_to(mpat, e3s.x2(), e3s.y2());
+			qStopColors[offset - 1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
+			qStopColors[offset].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
+			qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
+			cairo_pattern_mesh_end_patch(mpat);
+			cairo_pattern_mesh_begin_patch(mpat);
+			cairo_pattern_mesh_move_to(mpat, e3s.x2(), e3s.y2());
+			cairo_pattern_mesh_line_to(mpat, e3.x2(), e3.y2());
+			cairo_pattern_mesh_line_to(mpat, e4.x2(), e4.y2());
+			cairo_pattern_mesh_line_to(mpat, e4s.x2(), e4s.y2());
+			qStopColors[offset - 1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
+			qStopColors[offset].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
+			qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
+			cairo_pattern_mesh_end_patch(mpat);
+			cairo_pattern_mesh_begin_patch(mpat);
+			cairo_pattern_mesh_move_to(mpat, e4s.x2(), e4s.y2());
+			cairo_pattern_mesh_line_to(mpat, e4.x2(), e4.y2());
+			cairo_pattern_mesh_line_to(mpat, e1.x2(), e1.y2());
+			cairo_pattern_mesh_line_to(mpat, e1s.x2(), e1s.y2());
+			qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
+			qStopColors[offset].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
+			qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
+			cairo_pattern_mesh_end_patch(mpat);
+		}
+	}
+	cairo_pattern_set_filter(mpat, CAIRO_FILTER_GOOD);
+	cairo_set_source(cr, mpat);
+	cairo_paint_with_alpha(cr, 1.0);
+	pat = cairo_pattern_create_for_surface(img);
+	cairo_pattern_set_extend(pat, CAIRO_EXTEND_PAD);
+	cairo_pattern_set_filter(pat, CAIRO_FILTER_GOOD);
+
+	cairo_set_source (m_cr, pat);
+	cairo_clip_preserve (m_cr);
+
+	if (m_maskMode > 0)
+	{
+		/*cairo_pattern_t *patM = getMaskPattern();
+		setRasterOp(m_blendModeFill);
+		cairo_mask(m_cr, patM);
+		if ((m_maskMode == 2) || (m_maskMode == 4) || (m_maskMode == 5) || (m_maskMode == 6))
+			cairo_surface_destroy(imageMask);
+		cairo_pattern_destroy (patM);*/
+	}
+	else
+	{
+		setRasterOp(m_blendModeFill);
+		cairo_paint_with_alpha (m_cr, m_fillTrans);
+	}
+	cairo_pattern_destroy (pat);
+
+	if (img) cairo_surface_destroy(img);
+	if (mpat) cairo_pattern_destroy(mpat);
+	if (cr) cairo_destroy( cr );
+}
+
+void ScPainterEx_Cairo::drawMeshGradient( const QRect& rect )
+{
+	cairo_pattern_t *pat = NULL;
+	cairo_surface_t *img = NULL;
+	cairo_t *cr = NULL;
+	cairo_pattern_t *mpat = NULL;
+	VColorStopEx* stop = NULL;
+	QColor color;
+
+	double p3x = m_gradPatchP3.x();
+	double p3y = m_gradPatchP3.y();
+	img = cairo_surface_create_similar(cairo_get_target(m_cr), CAIRO_CONTENT_COLOR_ALPHA, p3x, p3y);
+	cr  = cairo_create(img);
+	cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
+	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+	cairo_set_tolerance(cr, 0.5 );
+	double r, g, b, a;
+	mpat = cairo_pattern_create_mesh();
+	for (int grow = 0; grow < m_meshGradientArray.count()-1; grow++)
+	{
+		for (int gcol = 0; gcol < m_meshGradientArray[grow].count()-1; gcol++)
+		{
+			meshPoint mp1 = m_meshGradientArray[grow][gcol];
+			meshPoint mp2 = m_meshGradientArray[grow][gcol+1];
+			meshPoint mp3 = m_meshGradientArray[grow+1][gcol+1];
+			meshPoint mp4 = m_meshGradientArray[grow+1][gcol];
+			cairo_pattern_mesh_begin_patch(mpat);
+			cairo_pattern_mesh_move_to(mpat, mp1.gridPoint.x(), mp1.gridPoint.y());
+			cairo_pattern_mesh_curve_to(mpat, mp1.controlRight.x(), mp1.controlRight.y(), mp2.controlLeft.x(), mp2.controlLeft.y(), mp2.gridPoint.x(), mp2.gridPoint.y());
+			cairo_pattern_mesh_curve_to(mpat, mp2.controlBottom.x(), mp2.controlBottom.y(), mp3.controlTop.x(), mp3.controlTop.y(), mp3.gridPoint.x(), mp3.gridPoint.y());
+			cairo_pattern_mesh_curve_to(mpat, mp3.controlLeft.x(), mp3.controlLeft.y(), mp4.controlRight.x(), mp4.controlRight.y(), mp4.gridPoint.x(), mp4.gridPoint.y());
+			cairo_pattern_mesh_curve_to(mpat, mp4.controlTop.x(), mp4.controlTop.y(), mp1.controlBottom.x(), mp1.controlBottom.y(), mp1.gridPoint.x(), mp1.gridPoint.y());
+			cairo_pattern_mesh_set_control_point(mpat, 0, mp1.controlColor.x(),  mp1.controlColor.y());
+			cairo_pattern_mesh_set_control_point(mpat, 1, mp2.controlColor.x(),  mp2.controlColor.y());
+			cairo_pattern_mesh_set_control_point(mpat, 2, mp3.controlColor.x(),  mp3.controlColor.y());
+			cairo_pattern_mesh_set_control_point(mpat, 3, mp4.controlColor.x(),  mp4.controlColor.y());
+			mp1.color.getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
+			mp2.color.getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
+			mp3.color.getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
+			mp4.color.getRgbF(&r, &g, &b, &a);
+			cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
+			cairo_pattern_mesh_end_patch(mpat);
+		}
+	}
+	cairo_pattern_set_filter(mpat, CAIRO_FILTER_BEST);
+	cairo_set_source(cr, mpat);
+	cairo_paint_with_alpha(cr, 1.0);
+	pat = cairo_pattern_create_for_surface(img);
+	cairo_pattern_set_extend(pat, CAIRO_EXTEND_NONE);
+	cairo_pattern_set_filter(pat, CAIRO_FILTER_BEST);
+
+	cairo_set_source (m_cr, pat);
+	cairo_clip_preserve (m_cr);
+
+	if (m_maskMode > 0)
+	{
+		/*cairo_pattern_t *patM = getMaskPattern();
+		setRasterOp(m_blendModeFill);
+		cairo_mask(m_cr, patM);
+		if ((m_maskMode == 2) || (m_maskMode == 4) || (m_maskMode == 5) || (m_maskMode == 6))
+			cairo_surface_destroy(imageMask);
+		cairo_pattern_destroy (patM);*/
+	}
+	else
+	{
+		setRasterOp(m_blendModeFill);
+		cairo_paint_with_alpha (m_cr, m_fillTrans);
+	}
+	cairo_pattern_destroy (pat);
+
+	if (img) cairo_surface_destroy(img);
+	if (mpat) cairo_pattern_destroy(mpat);
+	if (cr) cairo_destroy( cr );
+}
+
+void ScPainterEx_Cairo::drawFreeMeshGradient( const QRect& rect )
+{
+	cairo_pattern_t *pat = NULL;
+	cairo_surface_t *img = NULL;
+	cairo_t *cr = NULL;
+	cairo_pattern_t *mpat = NULL;
+	VColorStopEx* stop = NULL;
+	QColor color;
+
+	double p3x = m_gradPatchP3.x();
+	double p3y = m_gradPatchP3.y();
+	img = cairo_surface_create_similar(cairo_get_target(m_cr), CAIRO_CONTENT_COLOR_ALPHA, p3x, p3y);
+	cr = cairo_create(img);
+	cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
+	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+	cairo_set_tolerance(cr, 0.5 );
+	double r, g, b, a;
+	mpat = cairo_pattern_create_mesh();
+	for (int col = 0; col < m_meshGradientPatches.count(); col++)
+	{
+		meshGradientPatch patch = m_meshGradientPatches[col];
+		meshPoint mp1 = patch.TL;
+		meshPoint mp2 = patch.TR;
+		meshPoint mp3 = patch.BR;
+		meshPoint mp4 = patch.BL;
+		cairo_pattern_mesh_begin_patch(mpat);
+		cairo_pattern_mesh_move_to(mpat, mp1.gridPoint.x(), mp1.gridPoint.y());
+		cairo_pattern_mesh_curve_to(mpat, mp1.controlRight.x(), mp1.controlRight.y(), mp2.controlLeft.x(), mp2.controlLeft.y(), mp2.gridPoint.x(), mp2.gridPoint.y());
+		cairo_pattern_mesh_curve_to(mpat, mp2.controlBottom.x(), mp2.controlBottom.y(), mp3.controlTop.x(), mp3.controlTop.y(), mp3.gridPoint.x(), mp3.gridPoint.y());
+		cairo_pattern_mesh_curve_to(mpat, mp3.controlLeft.x(), mp3.controlLeft.y(), mp4.controlRight.x(), mp4.controlRight.y(), mp4.gridPoint.x(), mp4.gridPoint.y());
+		cairo_pattern_mesh_curve_to(mpat, mp4.controlTop.x(), mp4.controlTop.y(), mp1.controlBottom.x(), mp1.controlBottom.y(), mp1.gridPoint.x(), mp1.gridPoint.y());
+		cairo_pattern_mesh_set_control_point(mpat, 0, mp1.controlColor.x(),  mp1.controlColor.y());
+		cairo_pattern_mesh_set_control_point(mpat, 1, mp2.controlColor.x(),  mp2.controlColor.y());
+		cairo_pattern_mesh_set_control_point(mpat, 2, mp3.controlColor.x(),  mp3.controlColor.y());
+		cairo_pattern_mesh_set_control_point(mpat, 3, mp4.controlColor.x(),  mp4.controlColor.y());
+		mp1.color.getRgbF(&r, &g, &b, &a);
+		cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
+		mp2.color.getRgbF(&r, &g, &b, &a);
+		cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
+		mp3.color.getRgbF(&r, &g, &b, &a);
+		cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
+		mp4.color.getRgbF(&r, &g, &b, &a);
+		cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
+		cairo_pattern_mesh_end_patch(mpat);
+	}
+	cairo_pattern_set_filter(mpat, CAIRO_FILTER_BEST);
+	cairo_set_source(cr, mpat);
+	cairo_paint_with_alpha(cr, 1.0);
+	pat = cairo_pattern_create_for_surface(img);
+	cairo_pattern_set_extend(pat, CAIRO_EXTEND_NONE);
+	cairo_pattern_set_filter(pat, CAIRO_FILTER_BEST);
+	
+	cairo_set_source (m_cr, pat);
+	cairo_clip_preserve (m_cr);
+
+	if (m_maskMode > 0)
+	{
+		/*cairo_pattern_t *patM = getMaskPattern();
+		setRasterOp(m_blendModeFill);
+		cairo_mask(m_cr, patM);
+		if ((m_maskMode == 2) || (m_maskMode == 4) || (m_maskMode == 5) || (m_maskMode == 6))
+			cairo_surface_destroy(imageMask);
+		cairo_pattern_destroy (patM);*/
+	}
+	else
+	{
+		setRasterOp(m_blendModeFill);
+		cairo_paint_with_alpha (m_cr, m_fillTrans);
+	}
+	cairo_pattern_destroy (pat);
+
+	if (img) cairo_surface_destroy(img);
+	if (mpat) cairo_pattern_destroy(mpat);
+	if (cr) cairo_destroy( cr );
+}
+
+void ScPainterEx_Cairo::getClipPathDimensions( QRect& r )
+{
+	double left = 0.0, right = 0.0, bottom = 0.0, top = 0.0;
+	cairo_clip_extents(m_cr, &left, &bottom, &right, &top);
+	r.setLeft( left );
+	r.setRight( right );
+	r.setBottom( bottom );
+	r.setTop( top );
+}

Modified: trunk/Scribus/scribus/scpainterex_cairo.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17263&path=/trunk/Scribus/scribus/scpainterex_cairo.h
==============================================================================
--- trunk/Scribus/scribus/scpainterex_cairo.h (original)
+++ trunk/Scribus/scribus/scpainterex_cairo.h Tue Jan 31 00:04:40 2012
@@ -10,6 +10,8 @@
 
 #include <cairo.h>
 #include "scpainterexbase.h"
+
+#include "mesh.h"
 
 class ScPainterEx_Cairo : public ScPainterExBase
 {
@@ -49,8 +51,21 @@
 	virtual bool fillRule() { return m_fillRule; }
 	virtual void setFillMode( int fill );
 	virtual int  fillMode() { return m_fillMode; }
-	virtual void setGradient( VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc = FPoint(0,0));
-	virtual void setPattern ( ScPattern* pattern, QTransform& patternTransform );
+	virtual void setStrokeMode( int fill );
+	virtual int  strokeMode() { return m_strokeMode; }
+	virtual void setGradient( VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew);
+	virtual void setPattern(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY);
+
+	virtual void setMaskMode( int mask );
+	virtual void setGradientMask(VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew);
+	virtual void setPatternMask(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY);
+
+	virtual void set4ColorGeometry(FPoint p1, FPoint p2, FPoint p3, FPoint p4, FPoint c1, FPoint c2, FPoint c3, FPoint c4);
+	virtual void set4ColorColors(const ScColorShade& col1, const ScColorShade& col2, const ScColorShade& col3, const ScColorShade& col4);
+	virtual void setDiamondGeometry(FPoint p1, FPoint p2, FPoint p3, FPoint p4, FPoint c1, FPoint c2, FPoint c3, FPoint c4, FPoint c5);
+	virtual void setMeshGradient(FPoint p1, FPoint p2, FPoint p3, FPoint p4, QList<QList<meshPoint> > meshArray);
+	virtual void setMeshGradient(FPoint p1, FPoint p2, FPoint p3, FPoint p4, QList<meshGradientPatch> meshPatches);
+
 	virtual void setClipPath();
 
 	virtual void drawImage( ScImage *image, ScPainterExBase::ImageMode mode );
@@ -79,6 +94,8 @@
 	virtual void restore();
 
 	virtual void setRasterOp( int op );
+	virtual void setBlendModeFill( int blendMode );
+	virtual void setBlendModeStroke( int blendMode );
 
 private:
 
@@ -86,6 +103,10 @@
 	void drawGradient( VGradientEx& gradient );
 	void drawLinearGradient( VGradientEx& gradient, const QRect& rect );
 	void drawCircularGradient( VGradientEx& gradient, const QRect& rect );
+	void drawFourColorGradient( const QRect& rect );
+	void drawDiamondGradient( VGradientEx& gradient, const QRect& rect );
+	void drawMeshGradient( const QRect& rect );
+	void drawFreeMeshGradient( const QRect& rect );
 	void getClipPathDimensions( QRect& r );
 
 	ScribusDoc* m_doc;
@@ -94,16 +115,64 @@
 	unsigned int m_height;
 	QTransform m_matrix;
 	QFont m_font;
+/* Layer blend mode*/
+	int  m_blendModeLayer;
+	int  m_blendModeFill;
+	int  m_blendModeStroke;
 /* Filling */
 	ScColorShade m_fillColor;
 	double m_fillTrans;
 	bool   m_fillRule;
 	int    m_fillMode;			// 0 = none, 1 = solid, 2 = gradient
 	int    m_gradientMode;		// 1 = linear, 2 = radial
+
+	double m_patternScaleX;
+	double m_patternScaleY;
+	double m_patternOffsetX;
+	double m_patternOffsetY;
+	double m_patternRotation;
+	double m_patternSkewX;
+	double m_patternSkewY;
+	bool   m_patternMirrorX;
+	bool   m_patternMirrorY;
+
+	FPoint m_gradPatchP1;
+	FPoint m_gradPatchP2;
+	FPoint m_gradPatchP3;
+	FPoint m_gradPatchP4;
+	FPoint m_gradControlP1;
+	FPoint m_gradControlP2;
+	FPoint m_gradControlP3;
+	FPoint m_gradControlP4;
+	FPoint m_gradControlP5;
+	ScColorShade m_gradPatchColor1;
+	ScColorShade m_gradPatchColor2;
+	ScColorShade m_gradPatchColor3;
+	ScColorShade m_gradPatchColor4;
+	QList<QList<meshPoint> > m_meshGradientArray;
+	QList<meshGradientPatch> m_meshGradientPatches;
+
+	double m_gradientScale;
+	double m_gradientSkew;
 /* Stroking */
 	ScColorShade m_strokeColor;
 	double m_strokeTrans;
 	double m_lineWidth;
+	int    m_strokeMode;				// 0 = none, 1 = solid, 2 = gradient 3 = pattern
+/* Masking */
+	int    m_maskMode;				// 0 = none, 1 = gradient 2 = pattern
+	double m_maskPatternScaleX;
+	double m_maskPatternScaleY;
+	double m_maskPatternOffsetX;
+	double m_maskPatternOffsetY;
+	double m_maskPatternRotation;
+	double m_maskPatternSkewX;
+	double m_maskPatternSkewY;
+	bool   m_maskPatternMirrorX;
+	bool   m_maskPatternMirrorY;
+	double m_maskGradientScale;
+	double m_maskGradientSkew;
+
 /* Grayscale conversion option */
 	bool   m_convertToGray;
 

Modified: trunk/Scribus/scribus/scpainterex_ps2.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17263&path=/trunk/Scribus/scribus/scpainterex_ps2.cpp
==============================================================================
--- trunk/Scribus/scribus/scpainterex_ps2.cpp (original)
+++ trunk/Scribus/scribus/scpainterex_ps2.cpp Tue Jan 31 00:04:40 2012
@@ -1,1392 +1,1410 @@
-
-/*
-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.
-*/
-/* This file is part of the KDE project.
-   Copyright (C) 2001, 2002, 2003 The Karbon Developers
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public
-   License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public License
-   along with this library; see the file COPYING.LIB.  If not, write to
-   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.
-*/
-/* Adapted for Scribus 22.08.2003 by Franz Schmid */
-// kopainter/libart wrapper
-
-#include "scpainterex_ps2.h"
-
-#include <cfloat>
-#include <QPaintDevice>
-#include <QPixmap>
-#include <QImage>
-
-#include <iostream>
-#include <memory>
-using namespace std;
- 
-#include <cmath>
-#include "colormgmt/sccolormgmtengine.h"
-#include "sccolorengine.h"
-#include "util.h"
-
-ScPs2OutputParams::ScPs2OutputParams(ScribusDoc* doc)
-{
-	document = doc;
-	colorMode = ScPainterExBase::rgbMode;
-	reloadImages = true;
-	resolution = 72;
-	useProfiles = false;
-	toGray = false;
-	mirrorH = false;
-	mirrorV = false;
-	hProfile = NULL;
-	rgbToOutputColorTransform = NULL;
-	rgbToOutputImageTransform = NULL;
-	cmykToOutputColorTransform = NULL;
-	cmykToOutputImageTransform = NULL;
-}
-
-ScPainterEx_Ps2::ScPainterEx_Ps2(QIODevice* iodev, QRect& rect, ScPs2OutputParams& options ) : ScPainterExBase()
-{
-	m_stream.setDevice( iodev );
-	m_colorMode = options.colorMode;
-	m_encoding  = Ascii85Encoding;
-	m_options = options;
-	m_width = rect.width();
-	m_height= rect.height();
-	m_x = rect.left();
-	m_y = rect.top();
-	m_fillColor = ScColorShade( QColor(0,0,0), 100 );
-	m_strokeColor = ScColorShade( QColor(0,0,0), 100 );
-	m_fillTrans = 1.0;
-	m_strokeTrans = 1.0;
-	m_fillRule = true;
-	m_fillMode = 1;
-	m_lineWidth = 1.0;
-	m_offset = 0;
-	m_array.clear();
-	m_lineEnd = Qt::SquareCap;
-	m_lineJoin = Qt::RoundJoin;
-	m_fillGradient = VGradientEx(VGradientEx::linear);
-	m_strokeGradient = VGradientEx(VGradientEx::linear);
-	m_matrix = QTransform();
-	m_pageTrans = QTransform();
-	// Path state
-	m_pathIsClosed = true;
-	m_drawingClosedPath = false;
-	// TODO : set proper values
-	m_deviceDimX = 0;
-	m_deviceDimY = 0;
-	m_deviceResX = 0;
-	m_deviceResY = 0;
-	clear();
-}
-
-ScPainterEx_Ps2::~ScPainterEx_Ps2()
-{
-}
-
-ScPainterExBase::ImageMode ScPainterEx_Ps2::imageMode()
-{
-	ImageMode imageMode;
-	if (m_options.hProfile && m_options.rgbToOutputImageTransform && m_options.cmykToOutputImageTransform)
-		imageMode = rawImages;
-	else if (m_colorMode == cmykMode)
-		imageMode = cmykImages;
-	else
-		imageMode = rgbImages;
-	return imageMode;
-}
-
-void ScPainterEx_Ps2::transformImage( QImage* image, uchar* data, int scan)
-{
-	int rgb, grey;
-	int imageWidth = image->width();
-	int imageHeight = image->height();
-
-	QRgb*  pscani;
-	uchar *pscand;
-
-	pscand = data;
-	for ( int j = 0; j < imageHeight; j++ )
-	{
-		pscani = (QRgb *) image->scanLine(j);
-		for (int i = 0; i < imageWidth; i++ )
-		{
-			rgb = pscani[i];
-			grey = qRound(0.3 * qRed(rgb)) + qRound(0.59 * qGreen(rgb)) + qRound(0.11 * qBlue(rgb));
-			pscand[i] = grey;
-		}
-		pscand += scan;
-	}
-
-}
-
-void ScPainterEx_Ps2::begin()
-{
-}
-
-void ScPainterEx_Ps2::end()
-{
-
-}
-
-void ScPainterEx_Ps2::clear()
-{
-
-}
-
-void ScPainterEx_Ps2::clear( ScColorShade &c )
-{
-
-}
-
-const QTransform ScPainterEx_Ps2::worldMatrix()
-{
-	return m_matrix;
-}
-
-void ScPainterEx_Ps2::setWorldMatrix( const QTransform &mat )
-{
-	m_matrix = mat;
-}
-
-void ScPainterEx_Ps2::transformPoint( const FPoint& in, FPoint& out )
-{
-	double x, y;
-	x = in.x() * m_matrix.m11() + in.y() * m_matrix.m21() + m_matrix.dx();
-	y = in.x() * m_matrix.m12() + in.y() * m_matrix.m22() + m_matrix.dy();
-	out.setX( x );
-	out.setY( y );
-}
-
-void ScPainterEx_Ps2::transformPoints( const FPoint* ArrayIn, FPoint* ArrayOut, uint length )
-{
-	for( uint i = 0; i < length; i++ )
-	{
-		transformPoint( ArrayIn[i], ArrayOut[i] );
-	}
-}
-
-void ScPainterEx_Ps2::translate( double x, double y )
-{
-	m_matrix.translate(x, y);
-}
-
-void ScPainterEx_Ps2::rotate( double r )
-{
-	m_matrix.rotate(r);
-}
-
-void ScPainterEx_Ps2::scale( double x, double y )
-{
-	m_matrix.scale(x, y);
-}
-
-void ScPainterEx_Ps2::moveTo( const double &x, const double &y )
-{
-	FPoint pp( x, y );
-	transformPoint( pp, pp );
-	m_stream << QString("%1 %2 moveto\n").arg(pp.x()).arg(pp.y());
-}
-
-void ScPainterEx_Ps2::lineTo( const double &x, const double &y )
-{
-	FPoint pp( x, y );
-	transformPoint( pp, pp );
-	m_stream << QString("%1 %2 lineto\n").arg(pp.x()).arg(pp.y());
-}
-
-void ScPainterEx_Ps2::curveTo( FPoint p1, FPoint p2, FPoint p3 )
-{
-	FPoint pps[3];
-	pps[0].setXY( p1.x(), p1.y() );
-	pps[1].setXY( p2.x(), p2.y() );
-	pps[2].setXY( p3.x(), p3.y() );
-	transformPoints( pps, pps, 3 );
-	m_stream << QString("%1 %2 %3 %4 %5 %6 curveto\n").arg(pps[0].x()).arg(pps[0].y()).arg(pps[1].x()).arg(pps[1].y()).arg(pps[2].x()).arg(pps[2].y());
-}
-
-void ScPainterEx_Ps2::newPath()
-{
-   m_stream << "newpath\n";
-   //pathIsClosed = false;
-}
-
-void ScPainterEx_Ps2::closePath()
-{
-	m_stream << "closepath\n";
-	m_pathIsClosed = true;
-}
-
-void ScPainterEx_Ps2::setFillRule( bool fillRule )
-{
-	m_fillRule = fillRule;
-}
-
-void ScPainterEx_Ps2::setFillMode( int fill )
-{
-	m_fillMode = fill;
-}
-
-void ScPainterEx_Ps2::setGradient(VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc)
-{
-	m_fillGradient.setType(mode);
-	m_fillGradient.setOrigin(orig);
-	m_fillGradient.setVector(vec);
-	m_fillGradient.setFocalPoint(foc);
-}
-
-void ScPainterEx_Ps2::setPattern( ScPattern* pattern, QTransform& patternTransform )
-{
-	m_pattern = pattern;
-	m_patternTransform = patternTransform;
-}
-
-void ScPainterEx_Ps2::fillTextPath()
-{
-	drawVPath( 0 );
-}
-
-void ScPainterEx_Ps2::strokeTextPath()
-{
-	if( m_lineWidth == 0 )
-		return;
-	drawVPath( 1 );
-}
-
-void ScPainterEx_Ps2::fillPath()
-{
-	if(!m_pathIsClosed)
-		closePath();
-	if( m_fillMode != 0)
-		drawVPath( 0 );
-}
-
-void ScPainterEx_Ps2::strokePath()
-{
-	if( m_lineWidth == 0 )
-		return;
-	save();
-	if(!m_pathIsClosed)
-		closePath();
-	drawVPath( 1 );
-	restore();
-}
-
-ScColorShade ScPainterEx_Ps2::pen()
-{
-	return m_strokeColor;
-}
-
-ScColorShade ScPainterEx_Ps2::brush()
-{
-	return m_fillColor;
-}
-
-void ScPainterEx_Ps2::setPen( const ScColorShade &c )
-{
-	m_strokeColor = c;
-}
-
-void ScPainterEx_Ps2::setPen( const ScColorShade &c, double w, Qt::PenStyle st, Qt::PenCapStyle ca, Qt::PenJoinStyle jo )
-{
-	m_offset = 0;
-	m_strokeColor = c;
-	m_lineWidth = w;
-	m_lineEnd = ca;
-	m_lineJoin = jo;
-	double Dt = qMax(2*w, 1.0);
-	double Da = qMax(6*w, 1.0);
-	m_array.clear();
-	if (st == Qt::DashLine)
-		m_array << Da << Dt;
-	else if (st == Qt::DotLine)
-		m_array << Dt;
-	else if (st == Qt::DashDotLine)
-		m_array << Da << Dt << Dt << Dt;
-	else if (st == Qt::DashDotDotLine)
-		m_array << Da << Dt << Dt << Dt << Dt << Dt; 
-}
-
-void ScPainterEx_Ps2::setLineWidth( double w )
-{
-	m_lineWidth = w;
-}
-
-void ScPainterEx_Ps2::setPenOpacity( double op )
-{
-	m_strokeTrans = op;
-}
-
-void ScPainterEx_Ps2::setDash(const QVector<double>& array, double ofs)
-{
-	m_array = array;
-	m_offset = ofs;
-}
-
-void ScPainterEx_Ps2::setBrush( const ScColorShade &c )
-{
-	m_fillColor = c;
-}
-
-void ScPainterEx_Ps2::setBrushOpacity( double op )
-{
-	m_fillTrans = op;
-}
-
-void ScPainterEx_Ps2::setOpacity( double op )
-{
-	m_fillTrans = op;
-	m_strokeTrans = op;
-}
-
-void ScPainterEx_Ps2::setFont( const QFont &f)
-{
-	m_font = f;
-}
-
-QFont ScPainterEx_Ps2::font()
-{
-	return m_font;
-}
-
-void ScPainterEx_Ps2::save()
-{
-	m_stack.push( m_matrix );
-	m_stream << "gsave\n";
-}
-
-void ScPainterEx_Ps2::restore()
-{
-	m_matrix = m_stack.pop();
-	m_stream << "grestore\n";
-}
-
-void ScPainterEx_Ps2::setRasterOp( int   )
-{
-}
-
-void ScPainterEx_Ps2::drawVPath( int mode )
-{
-	save();
-	if (mode == 0)
-	{
-		if (m_fillMode == ScPainterExBase::Gradient)
-			drawGradient( m_fillGradient );
-		else
-			putColor( m_fillColor, true );
-	}
-	else
-	{
-		double m11 = m_matrix.m11();
-		double m12 = m_matrix.m12();
-		double m21 = m_matrix.m21();
-		double m22 = m_matrix.m22();
-		double norm2 = m11 * m11 + m12 * m12 + m21 * m21 + m22 * m22;
-		double penScale = sqrt(norm2 /2.0);
-		double penWidth = (int) (m_lineWidth * penScale);
-		m_stream << QString("%1 setlinewidth\n").arg(penWidth);
-
-		m_stream << "[";
-		for( int i = 0; i < m_array.count();++ i )
-		{
-			m_stream << QString("%1").arg(m_array[i]) << " ";
-		}
-		m_stream << "]";
-		m_stream << " 0 setdash\n";
-
-		if( m_lineEnd == Qt::RoundCap )
-			m_stream << "1 setlinecap\n";
-		else if( m_lineEnd == Qt::SquareCap )
-			m_stream << "2 setlinecap\n";
-		else if( m_lineEnd == Qt::FlatCap )
-			m_stream << "0 setlinecap\n";
-		else
-			m_stream << "0 setlinecap\n";
-
-		if( m_lineJoin == Qt::RoundJoin )
-			m_stream << "1 setlinejoin\n";
-		else if( m_lineJoin == Qt::BevelJoin )
-			m_stream << "2 setlinejoin\n";
-		else if( m_lineJoin == Qt::MiterJoin )
-			m_stream << "0 setlinejoin\n";
-		else
-			m_stream << "0 setlinejoin\n";
-
-		putColor(m_strokeColor, false);
-	}
-	restore();
-}
-
-void ScPainterEx_Ps2::setClipPath()
-{
-	//TODO eoclip or clip?
-	m_stream << "clip newpath\n";
-	m_clipBBox = m_pathBBox;
-}
-
-void ScPainterEx_Ps2::putColor( ScColorShade& colorShade, bool doFill )
-{
-	ColorMode colorMode = m_colorMode;
-	int r = 0, g = 0, b = 0, gray = 0;
-	int c = 0, m = 0, y = 0, k = 0;
-	if ( m_options.toGray )
-	{
-		RGBColor rgb;
-		ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
-		rgb.getValues(r, g, b);
-		gray = qRound(0.3 * r + 0.59 * g + 0.11 * b);
-		if ( doFill && m_fillRule )
-			m_stream << QString("%1 setgray eofill\n").arg(gray/255.0);
-		else if ( doFill )
-			m_stream << QString("%1 setgray fill\n").arg(gray/255.0);
-		else
-			m_stream << QString("%1 setgray stroke\n").arg(gray/255.0);
-		return;
-	}
-	else if ( m_options.hProfile && m_options.rgbToOutputColorTransform && m_options.cmykToOutputColorTransform)
-	{
-		unsigned long colorIn[4];
-		unsigned long colorOut[4];
-		ScColorTransform cmsTranform = NULL;
-		if( colorShade.color.getColorModel() == colorModelRGB )
-		{
-			RGBColor rgb;
-			ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
-			colorIn[0] = rgb.r;
-			colorIn[1] = rgb.g;
-			colorIn[2] = rgb.b;
-			colorMode = rgbMode;
-			cmsTranform = m_options.rgbToOutputColorTransform;
-		} 
-		else
-		{
-			CMYKColor cmyk;
-			ScColorEngine::getShadeColorCMYK(colorShade.color, m_options.document, cmyk, colorShade.shade);
-			colorIn[0] = cmyk.c;
-			colorIn[1] = cmyk.m;
-			colorIn[2] = cmyk.y;
-			colorIn[3] = cmyk.k;
-			colorMode = cmykMode;
-			cmsTranform = m_options.cmykToOutputColorTransform;
-		}
-		cmsTranform.apply(colorIn, colorOut, 1 );
-		if (m_options.hProfile.colorSpace() == ColorSpace_Rgb)
-		{
-			r = colorOut[0] / 257;
-			g = colorOut[1] / 257;
-			b = colorOut[2] / 257;
-			colorMode = rgbMode;
-		}
-		else if (m_options.hProfile.colorSpace() == ColorSpace_Cmyk)
-		{
-			c = colorOut[0] / 257;
-			m = colorOut[1] / 257;
-			y = colorOut[2] / 257;
-			k = colorOut[3] / 257;
-			colorMode = cmykMode;
-		}
-	}
-	else if ( m_colorMode == rgbMode )
-	{
-		RGBColor rgb;
-		colorMode = rgbMode;
-		ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
-		rgb.getValues(r, g, b);
-	}
-	else if ( m_colorMode == cmykMode )
-	{
-		CMYKColor cmyk;
-		colorMode = cmykMode;
-		ScColorEngine::getShadeColorCMYK(colorShade.color, m_options.document, cmyk, colorShade.shade);
-		cmyk.getValues(c, m, y, k);
-	}
-
-	// Finally output to file
-	if ( colorMode == rgbMode )
-	{
-		if ( doFill && m_fillRule )
-			m_stream << QString("%1 %2 %3 setrgbcolor eofill\n").arg(r/255.0).arg(g/255.0).arg(b/255.0);
-		else if ( doFill )
-			m_stream << QString("%1 %2 %3 setrgbcolor fill\n").arg(r/255.0).arg(g/255.0).arg(b/255.0);
-		else
-			m_stream << QString("%1 %2 %3 setrgbcolor stroke\n").arg(r/255.0).arg(g/255.0).arg(b/255.0);			
-	}
-	else if ( colorMode == cmykMode )
-	{
-		QString colstr1 = QString("%1 %2 %3 %4 setcmykcolor").arg(c/255.0).arg(m/255.0).arg(y/255.0).arg(k/255.0);
-		if ( doFill && m_fillRule )
-			m_stream << colstr1 << " eofill\n";
-		else if ( doFill )
-			m_stream << colstr1 << " fill\n";
-		else
-			m_stream << colstr1 << " stroke\n";	
-	}
-}
-
-void ScPainterEx_Ps2::drawImage( ScImage *image, ScPainterExBase::ImageMode mode )
-{
-	bool rgbMode = (mode == ScPainterExBase::rgbImages);
-	bool rgbPicture = rgbMode || (mode == ScPainterExBase::rawImages && image->imgInfo.colorspace == ColorSpaceRGB);
-	bool cmykPicture = (mode == ScPainterExBase::cmykImages || (mode == ScPainterExBase::rawImages && image->imgInfo.colorspace == ColorSpaceCMYK)); 
-
-	if( rgbPicture )
-		drawRGBImage_ps2( image );
-	else if( cmykPicture )
-		drawCMYKImage_ps2( image );
-	else
-		qDebug( "ScPainterEx_Ps2::drawImage() : unknown image type" );
-}
-
-void ScPainterEx_Ps2::drawRGBImage_ps2( ScImage *image )
-{
-	save();
-	QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
-	m_stream << sc.arg(m_matrix.m11()).arg(m_matrix.m12()).arg(m_matrix.m21()).arg(m_matrix.m22()).arg(m_matrix.dx()).arg(m_matrix.dy());
-	m_stream << QString("%1 %2 scale\n").arg(image->width()).arg(image->height());
-	m_stream << "/DeviceRGB setcolorspace\n";
-	if (hasAlphaChannel(image))
-	{
-		QImage imgTemp = image->qImage();
-		QImage mask = imgTemp.createAlphaMask();
-		if (m_encoding == Ascii85Encoding)
-		{
-			m_stream << "currentfile /ASCII85Decode filter /ReusableStreamDecode filter\n";
-			writeRGBImageToStream_Ascii85(image);
-		}
-		else
-		{
-			m_stream << "currentfile /ASCIIHexDecode filter /ReusableStreamDecode filter\n";
-			writeRGBImageToStream_AsciiHex(image);
-		}
-		m_stream << "/myImage exch def\n";
-		m_stream << "currentfile /ASCIIHexDecode filter /ReusableStreamDecode filter\n";
-		writeMaskToStream(&mask);
-		m_stream << "/myMask exch def\n";
-		m_stream << QString("<<\n");
-		m_stream << QString("    /PaintType   1\n");
-		m_stream << QString("    /PatternType 1\n");
-		m_stream << QString("    /TilingType  3\n");
-		m_stream << QString("    /BBox        [ 0 0 1 1 ]\n");
-		m_stream << QString("    /XStep       2\n");
-		m_stream << QString("    /YStep       2\n");
-		m_stream << QString("    /PaintProc   {\n");
-		m_stream << QString("        pop\n");
-		m_stream << QString("        0 0 0 setrgbcolor\n");
-		m_stream << QString("        <<\n");
-		m_stream << QString("            /ImageType 1\n");
-		m_stream << QString("            /Width     %1\n").arg(image->width());
-		m_stream << QString("            /Height    %1\n").arg(image->height());
-		m_stream << QString("            /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
-		m_stream << QString("            /BitsPerComponent 8\n");
-		m_stream << QString("            /Decode [0 1 0 1 0 1]\n");
-		m_stream << QString("            /DataSource myImage\n");
-		m_stream << QString("        >>\n");
-		m_stream << QString("        image\n");
-		m_stream << QString("    }\n");
-		m_stream << QString(">> matrix makepattern setpattern\n");
-		m_stream << QString("<<\n");
-		m_stream << QString("    /ImageType 1\n");
-		m_stream << QString("    /Width %1 \n").arg(image->width());
-		m_stream << QString("    /Height %1 \n").arg(image->height());
-		m_stream << QString("    /BitsPerComponent 1\n");
-		m_stream << QString("    /Decode [1 0]\n");
-		m_stream << QString("    /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
-		m_stream << QString("    /DataSource myMask\n");
-		m_stream << QString(">>\n");
-		m_stream << QString("imagemask\n");
-	}
-	else
-	{
-		m_stream << QString("<<\n");
-		m_stream << QString("    /ImageType 1\n");
-		m_stream << QString("    /Width %1\n").arg(image->width());
-		m_stream << QString("    /Height %1\n").arg(image->height());
-		m_stream << QString("    /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
-		m_stream << QString("    /Decode [0 1 0 1 0 1]\n");
-		m_stream << QString("    /BitsPerComponent 8\n");
-		//TODO case where compression is available
-		if (m_encoding == Ascii85Encoding)
-		{
-			m_stream << QString("    /DataSource currentfile /ASCII85Decode filter\n");
-			m_stream << QString(">>\n");
-			m_stream << "image\n";
-			writeRGBImageToStream_Ascii85(image);
-		}
-		else
-		{
-			m_stream << QString("    /DataSource currentfile /ASCIIHexDecode filter\n");
-			m_stream << QString(">>\n");
-			m_stream << "image\n";
-			writeRGBImageToStream_AsciiHex(image);
-		}
-	}
-	restore();
-}
-
-void ScPainterEx_Ps2::drawCMYKImage_ps2( ScImage *image )
-{
-	save();
-	QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
-	m_stream << sc.arg(m_matrix.m11()).arg(m_matrix.m12()).arg(m_matrix.m21()).arg(m_matrix.m22()).arg(m_matrix.dx()).arg(m_matrix.dy());
-	m_stream << QString("%1 %2 scale\n").arg(image->width()).arg(image->height());
-	m_stream << "/DeviceCMYK setcolorspace\n";
-	// TODO case where image have a mask
-	bool haveMask = false;
-	if (haveMask)
-	{
-
-	}
-	else
-	{
-		m_stream << "<<\n";
-		m_stream << QString("    /ImageType 1\n");
-		m_stream << QString("    /Width %1\n").arg(image->width());
-		m_stream << QString("    /Height %1\n").arg(image->height());
-		m_stream << QString("    /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
-		m_stream << QString("    /Decode [0 1 0 1 0 1 0 1]\n");
-		m_stream << QString("    /BitsPerComponent 8\n");
-		//TODO case where compression is available
-		if (m_encoding == Ascii85Encoding)
-		{
-			m_stream << QString("    /DataSource currentfile /ASCII85Decode filter\n");
-			m_stream << QString(">>\n");
-			m_stream << "image\n";
-			writeCMYKImageToStream_Ascii85(image);
-		}
-		else
-		{
-			m_stream << QString("    /DataSource currentfile /ASCIIHexDecode filter\n");
-			m_stream << QString(">>\n");
-			m_stream << "image\n";
-			writeCMYKImageToStream_AsciiHex(image);
-		}
-	}
-	restore();
-}
-
-bool ScPainterEx_Ps2::hasAlphaChannel( ScImage* image )
-{
-	bool   hasAlpha = false;
-	int    width = image->width();
-	int    height = image->height();
-	for( int y = 0; y < height; y++ )
-	{
-		QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
-		for( int x = 0; x < width; ++x )
-		{
-			if( qAlpha(*imageBits) != 255 )
-			{
-				hasAlpha = true;
-				break;
-			}
-			imageBits++;
-		}
-	}
-	return hasAlpha;
-}
-
-void ScPainterEx_Ps2::writeMaskToStream( QImage* image )
-{
-	int    length = 0;
-	unsigned char bits;
-	int    width = image->width() / 8;
-	int    height = image->height();
-	if ((image->width() % 8) != 0)
-		width++;
-	for( int y = 0; y < height; ++y )
-	{
-		unsigned char* imageBits = image->scanLine(y);
-		for( int x = 0; x < width; x++ )
-		{
-			length++;
-			bits = imageBits[x];
-			m_stream << toHex(bits);
-			if ( (length % 49) == 0 )
-				m_stream << "\n";
-		}
-	}
-	m_stream << "\n>\n";
-}
-
-void ScPainterEx_Ps2::writeRGBImageToStream_Ascii85( ScImage* image )
-{
-	int  cindex;
-	int  pending = 0, written = 0;
-	bool allZero  = true;
-	unsigned char  four_tuple[4];
-	const char* ascii85;
-	quint32 value;
-
-	int width = image->width();
-	int height = image->height();
-	for( int y = 0; y < height; ++y )
-	{
-		QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
-		for( int x = 0; x < width; ++x )
-		{
-			cindex = 0;
-			while (cindex < 3)
-			{
-				if (cindex == 0)
-					four_tuple[pending++] = (uchar) qRed(*imageBits);
-				else if (cindex == 1)
-					four_tuple[pending++] = (uchar) qGreen(*imageBits);
-				else if (cindex == 2)
-					four_tuple[pending++] = (uchar) qBlue(*imageBits);
-				if (pending == 4) 
-				{
-					value   = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
-					ascii85 = toAscii85(value, allZero);
-					if (allZero)
-						m_stream << "z";
-					else
-						m_stream << ascii85;
-					written += ((allZero) ? 1 : 5);
-					if (written > 75)
-					{
-						m_stream << "\n";
-						written = 0;
-					}
-					pending = 0;
-				}
-				++cindex;
-			}
-			
-		}
-	}
-	if (pending) 
-	{
-		unsigned char five_tuple[6];
-		memset (four_tuple + pending, 0, 4 - pending);
-		value   = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
-		ascii85 = toAscii85(value, allZero);
-		memcpy (five_tuple, ascii85, 5);
-		five_tuple[pending + 1] = 0;
-		m_stream << (const char*) five_tuple;
-	}
-	m_stream << "~>\n";
-}
-
-void ScPainterEx_Ps2::writeRGBImageToStream_AsciiHex ( ScImage* image )
-{
-	int  length = 0;
-	int  width = image->width();
-	int  height = image->height();
-	for( int y = 0; y < height; ++y )
-	{
-		QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
-		for( int x = 0; x < width; ++x )
-		{
-			length++;
-			uchar r = (uchar) qRed(*imageBits);
-			m_stream << toHex(r);
-			uchar g = (uchar) qGreen(*imageBits);
-			m_stream << toHex(g);
-			uchar b = (uchar) qBlue(*imageBits);
-			m_stream << toHex(b);
-			if ( (length % 17) == 0 )
-				m_stream << "\n";
-			imageBits++;
-		}
-	}
-	m_stream << "\n>\n";
-}
-
-void ScPainterEx_Ps2::writeCMYKImageToStream_Ascii85( ScImage* image )
-{
-	int  written = 0;
-	bool allZero  = true;
-	unsigned char  four_tuple[4];
-	const char* ascii85;
-	quint32 value;
-
-	int width = image->width();
-	int height = image->height();
-	for( int y = 0; y < height; y++ )
-	{
-		QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
-		for( int x = 0; x < width; x++ )
-		{
-			four_tuple[0] = (uchar) qRed(*imageBits);
-			four_tuple[1] = (uchar) qGreen(*imageBits);
-			four_tuple[2] = (uchar) qBlue(*imageBits);
-			four_tuple[3] = (uchar) qAlpha(*imageBits);
-			value   = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
-			ascii85 = toAscii85(value, allZero);
-			if (allZero)
-				m_stream << "z";
-			else
-				m_stream << ascii85;
-			written += ((allZero) ? 1 : 5);
-			if (written > 75)
-			{
-				m_stream << "\n";
-				written = 0;
-			}
-			imageBits++;
-		}
-	}
-	m_stream << "~>\n";
-}
-
-void ScPainterEx_Ps2::writeCMYKImageToStream_AsciiHex( ScImage* image )
-{
-	int length = 0;
-	int width = image->width();
-	int height = image->height();
-	for( int y = 0; y < height; ++y )
-	{
-		QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
-		for( int x = 0; x < width; ++x )
-		{
-			length++;
-			uchar c = (uchar) qRed(*imageBits);
-			m_stream << toHex(c);
-			uchar m = (uchar) qGreen(*imageBits);
-			m_stream << toHex(m);
-			uchar y = (uchar) qBlue(*imageBits);
-			m_stream << toHex(y);
-			uchar k = (uchar) qAlpha(*imageBits);
-			m_stream << toHex(k);
-			if ( (length % 13) == 0 )
-				m_stream << "\n";
-			imageBits++;
-		}
-	}
-	m_stream << "\n>\n";
-}
-
-void ScPainterEx_Ps2::setupPolygon(FPointArray *points, bool closed)
-{
-	bool nPath = true;
-	FPoint np, np1, np2, np3;
-	if (points->size() > 3)
-	{
-		newPath();
-		for (uint poi=0; poi<points->size()-3; poi += 4)
-		{
-			if (points->point(poi).x() > 900000)
-			{
-				nPath = true;
-				continue;
-			}
-			if (nPath)
-			{
-				np = points->point(poi);
-				// TODO startfigure needed?
-				moveTo( np.x(), np.y() );
-				nPath = false;
-			}
-			np = points->point(poi);
-			np1 = points->point(poi+1);
-			np2 = points->point(poi+3);
-			np3 = points->point(poi+2);
-			if ((np == np1) && (np2 == np3))
-				lineTo( np3.x(), np3.y() );
-			else
-				curveTo(np1, np2, np3);
-		}
-		if (closed)
-		{
-			closePath();
-			m_drawingClosedPath = true;
-		}
-	}
-	getPathBoundingBox( points, m_pathBBox );
-}
-
-void ScPainterEx_Ps2::drawPolygon()
-{
-	fillPath();
-}
-
-void ScPainterEx_Ps2::drawPolyLine()
-{
-	strokePath();
-}
-
-void ScPainterEx_Ps2::drawLine(FPoint start, FPoint end)
-{
-	newPath();
-	moveTo(start.x(), start.y());
-	lineTo(end.x(), end.y());
-	strokePath();
-}
-
-void ScPainterEx_Ps2::drawRect(double x, double y, double w, double h)
-{
-	newPath();
-	moveTo( x, y );
-	lineTo( x+w, y );
-	lineTo( x+w, y+h );
-	lineTo( x, y+h );
-	lineTo( x, y );
-	closePath();
-	m_drawingClosedPath = true;
-	fillPath();
-	strokePath();
-}
-
-void ScPainterEx_Ps2::drawGradient( VGradientEx& gradient )
-{
-	QRect clipPathRect;
-	save();
-	//setClipPath();
-	m_stream << "clip\n";
-	m_clipBBox = m_pathBBox;
-	if ( gradient.type() == VGradientEx::linear )
-		drawLinearGradient( gradient, m_clipBBox );
-	else if ( gradient.type() == VGradientEx::radial )
-		drawCircularGradient( gradient, m_clipBBox );
-	restore();
-}
-
-void ScPainterEx_Ps2::drawLinearGradient( VGradientEx& gradient, const QRect& rect )
-{
-	if (m_colorMode == cmykMode)
-		drawLinearGradient_CMYK(gradient, rect);
-	else
-		drawLinearGradient_RGB(gradient, rect);
-}
-
-void ScPainterEx_Ps2::drawLinearGradient_RGB( VGradientEx& gradient, const QRect& rect )
-{
-	int r1, g1, b1;
-	int r2, g2, b2;
-	double cosa, sina;
-	double ramp1, ramp2;
-	double scale1, scale2;
-	double length, scale;
-	double x1, y1, x2, y2, dx, dy;
-	int clipBoxWidth, clipBoxHeight, maxDim;
-	QList<VColorStopEx*> colorStops = gradient.colorStops();
-	VColorStopEx stop1( *colorStops[0] );
-	VColorStopEx stop2( *colorStops[0] );
-	RGBColor rgb;
-	FPoint p1, p2;
-	QColor color;
-
-	if ( gradient.Stops() < 2 ) 
-		return;
-
-	clipBoxWidth = rect.width();
-	clipBoxHeight = rect.height();
-	maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
-	if ( maxDim <= 0 ) return;
-	
-	scale1 = sqrt( m_matrix.m11() * m_matrix.m11() + m_matrix.m12() * m_matrix.m12() );
-	scale2 = sqrt( m_matrix.m21() * m_matrix.m21() + m_matrix.m22() * m_matrix.m22() );
-
-	x1 = m_matrix.dx() + gradient.origin().x() * m_matrix.m11();
-	y1 = m_matrix.dy() + gradient.origin().y() * m_matrix.m22();
-	x2 = m_matrix.dx() + gradient.vector().x() * m_matrix.m11();
-	y2 = m_matrix.dy() + gradient.vector().y() * m_matrix.m22();
-	p1.setXY( x1, y1 );
-	p2.setXY( x2, y2 );
-
-	dx = ( p2.x() - p1.x() );
-	dy = ( p2.y() - p1.y() );
-	length = sqrt(( dx * dx + dy * dy ));
-	if ( length == 0.0 )
-		scale = 1.0;
-	else
-		scale = 1.0 / length;
-	cosa = dx * scale;
-	sina = dy * scale;
-
-	QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
-	m_stream << sc.arg(cosa).arg(sina).arg(-sina).arg(cosa).arg(x1).arg(y1);
-
-	ramp1 = stop1.rampPoint;
-	ScColorEngine::getShadeColorRGB(stop1.color, m_options.document, rgb, stop1.shade);
-	rgb.getValues(r1, g1, b1);
-	m_stream << QString("%1 %2 %3 setrgbcolor fill\n").arg(r1/255.0).arg(g1/255.0).arg(b1/255.0);
-
-	for( uint index = 1; index < gradient.Stops(); index++)
-	{
-		stop2 = *colorStops[index];
-		ramp2 = stop2.rampPoint;
-		ScColorEngine::getShadeColorRGB(stop2.color, m_options.document, rgb, stop2.shade);
-		rgb.getValues(r2, g2, b2);
-		double xMin = length * ramp1;
-		double xMax = length * ramp2;
-
-		m_stream << QString("/x1 %1 def\n").arg(xMin);
-		m_stream << QString("/x2 %1 def\n").arg(xMax);
-		m_stream << QString("/r1 %1 def\n").arg(r1/255.0);
-		m_stream << QString("/g1 %1 def\n").arg(g1/255.0);
-		m_stream << QString("/b1 %1 def\n").arg(b1/255.0);
-		m_stream << QString("/r2 %1 def\n").arg(r2/255.0);
-		m_stream << QString("/g2 %1 def\n").arg(g2/255.0);
-		m_stream << QString("/b2 %1 def\n").arg(b2/255.0);
-		m_stream << QString("/maxd %1 def\n").arg(maxDim);
-		m_stream << QString("/mmaxd %1 def\n").arg(-maxDim/2.0);
-		m_stream << "r1 r2 sub abs 255 mul /dr exch def\n";
-		m_stream << "g1 g2 sub abs 255 mul /dg exch def\n";
-		m_stream << "b1 b2 sub abs 255 mul /db exch def\n";
-		m_stream << "dr dg add db add /colsteps exch def\n";
-		m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
-		m_stream << "x2 x1 sub colsteps div /xinc exch def\n";
-		m_stream << "xinc 2 mul /xinc2 exch def\n";
-		m_stream << "x2 xinc2 lt { /xinc2 x2 def } if\n";
-		m_stream << "r2 r1 sub colsteps div /rinc exch def\n";
-		m_stream << "g2 g1 sub colsteps div /ginc exch def\n";
-		m_stream << "b2 b1 sub colsteps div /binc exch def\n";
-		//m_stream << "r1 g1 b1 setrgbcolor\n";
-		//m_stream << "0 mmaxd maxd maxd rectfill\n";
-		m_stream << "0 1 colsteps\n";
-		m_stream << "{\n";
-		m_stream << "    r1 g1 b1 setrgbcolor\n";
-		m_stream << "    x1 mmaxd xinc2 maxd rectfill\n"; //rectfill is a ps2 operator
-		m_stream << "    x1 xinc add /x1 exch def\n";
-		m_stream << "    r1 rinc add /r1 exch def\n";
-		m_stream << "    g1 ginc add /g1 exch def\n";
-		m_stream << "    b1 binc add /b1 exch def\n";
-		m_stream << "} for\n";
-		m_stream << "x2 mmaxd maxd maxd rectfill\n";
-
-		stop1 = stop2;
-		ramp1 = ramp2;
-		r1 = r2;
-		g1 = g2;
-		b1 = b2;
-	}
-}
-
-void ScPainterEx_Ps2::drawLinearGradient_CMYK( VGradientEx& gradient, const QRect& rect )
-{
-	int c1, m1, j1, n1;
-	int c2, m2, j2, n2;
-	double cosa, sina;
-	double ramp1, ramp2;
-	double scale1, scale2;
-	double length, scale;
-	double x1, y1, x2, y2, dx, dy;
-	int clipBoxWidth, clipBoxHeight, maxDim;
-	QList<VColorStopEx*> colorStops = gradient.colorStops();
-	VColorStopEx stop1( *colorStops[0] );
-	VColorStopEx stop2( *colorStops[0] );
-	CMYKColor cmyk;
-	FPoint p1, p2;
-	QColor color;
-
-	if ( gradient.Stops() < 2 ) 
-		return;
-
-	clipBoxWidth = rect.width();
-	clipBoxHeight = rect.height();
-	maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
-	if ( maxDim <= 0 ) return;
-	
-	scale1 = sqrt( m_matrix.m11() * m_matrix.m11() + m_matrix.m12() * m_matrix.m12() );
-	scale2 = sqrt( m_matrix.m21() * m_matrix.m21() + m_matrix.m22() * m_matrix.m22() );
-
-	x1 = m_matrix.dx() + gradient.origin().x() * m_matrix.m11();
-	y1 = m_matrix.dy() + gradient.origin().y() * m_matrix.m22();
-	x2 = m_matrix.dx() + gradient.vector().x() * m_matrix.m11();
-	y2 = m_matrix.dy() + gradient.vector().y() * m_matrix.m22();
-	p1.setXY( x1, y1 );
-	p2.setXY( x2, y2 );
-
-	dx = ( p2.x() - p1.x() );
-	dy = ( p2.y() - p1.y() );
-	length = sqrt(( dx * dx + dy * dy ));
-	if ( length == 0.0 )
-		scale = 1.0;
-	else
-		scale = 1.0 / length;
-	cosa = dx * scale;
-	sina = dy * scale;
-
-	QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
-	m_stream << sc.arg(cosa).arg(sina).arg(-sina).arg(cosa).arg(x1).arg(y1);
-
-	ramp1 = stop1.rampPoint;
-	ScColorEngine::getShadeColorCMYK(stop1.color, m_options.document, cmyk, stop1.shade);
-	cmyk.getValues(c1, m1, j1, n1);
-	m_stream << QString("/DeviceCMYK setcolorspace\n");
-	m_stream << QString("%1 %2 %3 %4 setcolor fill\n").arg(c1/255.0).arg(m1/255.0).arg(j1/255.0).arg(n1/255.0);
-
-	for( uint index = 1; index < gradient.Stops(); index++)
-	{
-		stop2 = *colorStops[index];
-		ramp2 = stop2.rampPoint;
-		ScColorEngine::getShadeColorCMYK(stop2.color, m_options.document, cmyk, stop2.shade);
-		cmyk.getValues(c2, m2, j2, n2);
-		double xMin = length * ramp1;
-		double xMax = length * ramp2;
-
-		m_stream << QString("/x1 %1 def\n").arg(xMin);
-		m_stream << QString("/x2 %1 def\n").arg(xMax);
-		m_stream << QString("/c1 %1 def\n").arg(c1/255.0);
-		m_stream << QString("/m1 %1 def\n").arg(m1/255.0);
-		m_stream << QString("/y1 %1 def\n").arg(j1/255.0);
-		m_stream << QString("/k1 %1 def\n").arg(n1/255.0);
-		m_stream << QString("/c2 %1 def\n").arg(c2/255.0);
-		m_stream << QString("/m2 %1 def\n").arg(m2/255.0);
-		m_stream << QString("/y2 %1 def\n").arg(j2/255.0);
-		m_stream << QString("/k2 %1 def\n").arg(n2/255.0);
-		m_stream << QString("/maxd %1 def\n").arg(maxDim);
-		m_stream << QString("/mmaxd %1 def\n").arg(-maxDim/2.0);
-		m_stream << "c1 c2 sub abs 255 mul /dc exch def\n";
-		m_stream << "m1 m2 sub abs 255 mul /dm exch def\n";
-		m_stream << "y1 y2 sub abs 255 mul /dy exch def\n";
-		m_stream << "k1 k2 sub abs 255 mul /dk exch def\n";
-		m_stream << "dc dm add dy add dk add /colsteps exch def\n";
-		m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
-		m_stream << "x2 x1 sub colsteps div /xinc exch def\n";
-		m_stream << "xinc 2 mul /xinc2 exch def\n";
-		m_stream << "x2 xinc2 lt { /xinc2 x2 def } if\n";
-		m_stream << "c2 c1 sub colsteps div /cinc exch def\n";
-		m_stream << "m2 m1 sub colsteps div /minc exch def\n";
-		m_stream << "y2 y1 sub colsteps div /yinc exch def\n";
-		m_stream << "k2 k1 sub colsteps div /kinc exch def\n";
-		//m_stream << "r1 g1 b1 setrgbcolor\n";
-		//m_stream << "0 mmaxd maxd maxd rectfill\n";
-		m_stream << "0 1 colsteps\n";
-		m_stream << "{\n";
-		m_stream << "    c1 m1 y1 k1 setcolor\n";
-		m_stream << "    x1 mmaxd xinc2 maxd rectfill\n"; //rectfill is a ps2 operator
-		m_stream << "    x1 xinc add /x1 exch def\n";
-		m_stream << "    c1 cinc add /c1 exch def\n";
-		m_stream << "    m1 minc add /m1 exch def\n";
-		m_stream << "    y1 yinc add /y1 exch def\n";
-		m_stream << "    k1 kinc add /k1 exch def\n";
-		m_stream << "} for\n";
-		m_stream << "x2 mmaxd maxd maxd rectfill\n";
-
-		stop1 = stop2;
-		ramp1 = ramp2;
-		c1 = c2;
-		m1 = m2;
-		j1 = j2;
-		n1 = n2;
-	}
-}
-
-void ScPainterEx_Ps2::drawCircularGradient( VGradientEx& gradient, const QRect& rect )
-{
-	if (m_colorMode == cmykMode)
-		drawCircularGradient_CMYK(gradient, rect);
-	else
-		drawCircularGradient_RGB(gradient, rect);
-}
-
-void ScPainterEx_Ps2::drawCircularGradient_RGB( VGradientEx& gradient, const QRect& rect )
-{
-	int r1, g1, b1;
-	int r2, g2, b2;
-	double ramp1, ramp2;
-	double scale1, scale2;
-	int clipBoxWidth, clipBoxHeight, maxDim;
-	QList<VColorStopEx*> colorStops = gradient.colorStops();
-	VColorStopEx stop1( *colorStops[gradient.Stops() - 1] );
-	VColorStopEx stop2( *colorStops[gradient.Stops() - 1] );
-	RGBColor rgb;
-	QColor color;
-
-	clipBoxWidth = rect.width();
-	clipBoxHeight = rect.height();
-	maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
-	if ( maxDim <= 0 ) return;
-
-	scale1 = sqrt( m_matrix.m11() * m_matrix.m11() + m_matrix.m21() * m_matrix.m21() );
-	scale2 = sqrt( m_matrix.m12() * m_matrix.m12() + m_matrix.m22() * m_matrix.m22() );
-
-	FPoint pc( gradient.origin().x(), gradient.origin().y() );
-	FPoint pcz( gradient.origin().x(), gradient.origin().y() );
-	FPoint pf( gradient.focalPoint().x(), gradient.focalPoint().y() );
-	FPoint pfz( gradient.focalPoint().x(), gradient.focalPoint().y() );
-	FPoint pv( gradient.vector().x(), gradient.vector().y() );
-	transformPoint( pc, pc );
-	transformPoint( pf, pf );
-	transformPoint( pv, pv );
-	transformPoint( pcz, pcz );
-	transformPoint( pfz, pfz );
-	double cx = pcz.x();
-	double cy = pcz.y();
-	double rad = sqrt( pow(pv.x() -pc.x(), 2) + pow(pv.y() - pc.y(), 2) );
-
-	ramp2 = stop2.rampPoint;
-	ScColorEngine::getShadeColorRGB(stop2.color, m_options.document, rgb, stop2.shade);
-	rgb.getValues(r2, g2, b2);
-	m_stream << QString("%1 %2 %3 setrgbcolor fill\n").arg(r2).arg(g2).arg(b2);
-	if ( gradient.Stops() < 2 ) return;
-
-	for( int index = gradient.Stops() - 2; index >= 0; index--)
-	{
-		stop1 = *colorStops[index];
-		ramp1 = stop1.rampPoint;
-		ScColorEngine::getShadeColorRGB(stop1.color, m_options.document, rgb, stop1.shade);
-		rgb.getValues(r1, g1, b1);
-		int radMax = qRound(rad * ramp2);
-		int radMin = qRound(rad * ramp1);
-		
-		m_stream << QString("/rad1 %1 def\n").arg(radMax);
-		m_stream << QString("/rad2 %1 def\n").arg(radMin);
-		m_stream << QString("/circx %1 def\n").arg(cx);
-		m_stream << QString("/circy %1 def\n").arg(cy);
-		m_stream << QString("/r1 %1 def\n").arg(r1/255.0);
-		m_stream << QString("/g1 %1 def\n").arg(g1/255.0);
-		m_stream << QString("/b1 %1 def\n").arg(b1/255.0);
-		m_stream << QString("/r2 %1 def\n").arg(r2/255.0);
-		m_stream << QString("/g2 %1 def\n").arg(g2/255.0);
-		m_stream << QString("/b2 %1 def\n").arg(b2/255.0);
-		m_stream << "r1 r2 sub abs 255 mul /dr exch def\n";
-		m_stream << "g1 g2 sub abs 255 mul /dg exch def\n";
-		m_stream << "b1 b2 sub abs 255 mul /db exch def\n";
-		m_stream << "dr dg add db add /colsteps exch def\n";
-		m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
-		m_stream << "rad2 rad1 sub colsteps div /radinc exch def\n";
-		m_stream << "r1 r2 sub colsteps div /rinc exch def\n";
-		m_stream << "g1 g2 sub colsteps div /ginc exch def\n";
-		m_stream << "b1 b2 sub colsteps div /binc exch def\n";
-		m_stream << "0 1 colsteps\n";
-		m_stream << "{\n";
-		m_stream << "    r2 g2 b2 setrgbcolor\n";
-		m_stream << "    circx circy rad1 0 360 arc closepath fill\n"; 
-		m_stream << "    rad1 radinc add /rad1 exch def\n";
-		m_stream << "    r2 rinc add /r2 exch def\n";
-		m_stream << "    g2 ginc add /g2 exch def\n";
-		m_stream << "    b2 binc add /b2 exch def\n";
-		m_stream << "} for\n";
-
-		stop2 = stop1;
-		ramp2 = ramp1;
-		r2 = r1;
-		g2 = g1;
-		b2 = b1;
-	}
-}
-
-void ScPainterEx_Ps2::drawCircularGradient_CMYK( VGradientEx& gradient, const QRect& rect )
-{
-	int c1, m1, y1, k1;
-	int c2, m2, y2, k2;
-	double ramp1, ramp2;
-	double scale1, scale2;
-	int clipBoxWidth, clipBoxHeight, maxDim;
-	QList<VColorStopEx*> colorStops = gradient.colorStops();
-	VColorStopEx stop1( *colorStops[gradient.Stops() - 1] );
-	VColorStopEx stop2( *colorStops[gradient.Stops() - 1] );
-	CMYKColor cmyk;
-	QColor color;
-
-	clipBoxWidth = rect.width();
-	clipBoxHeight = rect.height();
-	maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
-	if ( maxDim <= 0 ) return;
-
-	scale1 = sqrt( m_matrix.m11() * m_matrix.m11() + m_matrix.m21() * m_matrix.m21() );
-	scale2 = sqrt( m_matrix.m12() * m_matrix.m12() + m_matrix.m22() * m_matrix.m22() );
-
-	FPoint pc( gradient.origin().x(), gradient.origin().y() );
-	FPoint pcz( gradient.origin().x(), gradient.origin().y() );
-	FPoint pf( gradient.focalPoint().x(), gradient.focalPoint().y() );
-	FPoint pfz( gradient.focalPoint().x(), gradient.focalPoint().y() );
-	FPoint pv( gradient.vector().x(), gradient.vector().y() );
-	transformPoint( pc, pc );
-	transformPoint( pf, pf );
-	transformPoint( pv, pv );
-	transformPoint( pcz, pcz );
-	transformPoint( pfz, pfz );
-	double cx = pcz.x();
-	double cy = pcz.y();
-	double rad = sqrt( pow(pv.x() -pc.x(), 2) + pow(pv.y() - pc.y(), 2) );
-
-	ramp2 = stop2.rampPoint;
-	ScColorEngine::getShadeColorCMYK(stop2.color, m_options.document, cmyk, stop2.shade);
-	cmyk.getValues(c2, m2, y2, k2);
-	m_stream << QString("/DeviceCMYK setcolorspace\n");
-	m_stream << QString("%0 %1 %2 %3 setcolor fill\n").arg(c2).arg(m2).arg(y2).arg(k2);
-	if ( gradient.Stops() < 2 ) return;
-
-	for( int index = gradient.Stops() - 2; index >= 0; index--)
-	{
-		stop1 = *colorStops[index];
-		ramp1 = stop1.rampPoint;
-		ScColorEngine::getShadeColorCMYK(stop1.color, m_options.document, cmyk, stop1.shade);
-		cmyk.getValues(c1, m1, y1, k1);
-		int radMax = qRound(rad * ramp2);
-		int radMin = qRound(rad * ramp1);
-		
-		m_stream << QString("/rad1 %1 def\n").arg(radMax);
-		m_stream << QString("/rad2 %1 def\n").arg(radMin);
-		m_stream << QString("/circx %1 def\n").arg(cx);
-		m_stream << QString("/circy %1 def\n").arg(cy);
-		m_stream << QString("/c1 %1 def\n").arg(c1/255.0);
-		m_stream << QString("/m1 %1 def\n").arg(m1/255.0);
-		m_stream << QString("/y1 %1 def\n").arg(y1/255.0);
-		m_stream << QString("/k1 %1 def\n").arg(k1/255.0);
-		m_stream << QString("/c2 %1 def\n").arg(c2/255.0);
-		m_stream << QString("/m2 %1 def\n").arg(m2/255.0);
-		m_stream << QString("/y2 %1 def\n").arg(y2/255.0);
-		m_stream << QString("/k2 %1 def\n").arg(k2/255.0);
-		m_stream << "c1 c2 sub abs 255 mul /dc exch def\n";
-		m_stream << "m1 m2 sub abs 255 mul /dm exch def\n";
-		m_stream << "y1 y2 sub abs 255 mul /dy exch def\n";
-		m_stream << "k1 k2 sub abs 255 mul /dk exch def\n";
-		m_stream << "dc dm add dy add dk add /colsteps exch def\n";
-		m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
-		m_stream << "rad2 rad1 sub colsteps div /radinc exch def\n";
-		m_stream << "c1 c2 sub colsteps div /cinc exch def\n";
-		m_stream << "m1 m2 sub colsteps div /minc exch def\n";
-		m_stream << "y1 y2 sub colsteps div /yinc exch def\n";
-		m_stream << "k1 k2 sub colsteps div /kinc exch def\n";
-		m_stream << "0 1 colsteps\n";
-		m_stream << "{\n";
-		m_stream << "    c2 m2 y2 k2 setcolor\n";
-		m_stream << "    circx circy rad1 0 360 arc closepath fill\n"; 
-		m_stream << "    rad1 radinc add /rad1 exch def\n";
-		m_stream << "    c2 cinc add /c2 exch def\n";
-		m_stream << "    m2 minc add /m2 exch def\n";
-		m_stream << "    y2 yinc add /y2 exch def\n";
-		m_stream << "    k2 kinc add /k2 exch def\n";
-		m_stream << "} for\n";
-
-		stop2 = stop1;
-		ramp2 = ramp1;
-		c2 = c1;
-		m2 = m1;
-		y2 = y1;
-		k2 = k1;
-	}
-}
-
-void ScPainterEx_Ps2::getPathBoundingBox( FPointArray* points, QRect& r )
-{
-	FPoint point;
-	double bottom = DBL_MAX, top   = DBL_MIN;
-	double left   = DBL_MAX, right = DBL_MIN;
-
-	r.setCoords(0, 0, 0, 0);
-
-	for( uint i = 0; i < points->size(); i++ )
-	{
-		point = points->point(i);
-		if( point.x() > 900000 )
-			continue;
-		transformPoint(point, point);
-		if( point.x() < left ) left = point.x();
-		if( point.x() > right ) right = point.x();
-		if( point.y() < bottom ) bottom = point.y();
-		if( point.y() > top ) top = point.y();
-	}
-	r.setCoords( qRound(left), qRound(bottom), qRound(right), qRound(top) );
-}
-
+
+/*
+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.
+*/
+/* This file is part of the KDE project.
+   Copyright (C) 2001, 2002, 2003 The Karbon Developers
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+*/
+/* Adapted for Scribus 22.08.2003 by Franz Schmid */
+// kopainter/libart wrapper
+
+#include "scpainterex_ps2.h"
+
+#include <cfloat>
+#include <QPaintDevice>
+#include <QPixmap>
+#include <QImage>
+
+#include <iostream>
+#include <memory>
+using namespace std;
+ 
+#include <cmath>
+#include "colormgmt/sccolormgmtengine.h"
+#include "sccolorengine.h"
+#include "util.h"
+
+ScPs2OutputParams::ScPs2OutputParams(ScribusDoc* doc)
+{
+	document = doc;
+	colorMode = ScPainterExBase::rgbMode;
+	reloadImages = true;
+	resolution = 72;
+	useProfiles = false;
+	toGray = false;
+	mirrorH = false;
+	mirrorV = false;
+	hProfile = NULL;
+	rgbToOutputColorTransform = NULL;
+	rgbToOutputImageTransform = NULL;
+	cmykToOutputColorTransform = NULL;
+	cmykToOutputImageTransform = NULL;
+}
+
+ScPainterEx_Ps2::ScPainterEx_Ps2(QIODevice* iodev, QRect& rect, ScPs2OutputParams& options ) : ScPainterExBase()
+{
+	m_stream.setDevice( iodev );
+	m_colorMode = options.colorMode;
+	m_encoding  = Ascii85Encoding;
+	m_options = options;
+	m_width = rect.width();
+	m_height= rect.height();
+	m_x = rect.left();
+	m_y = rect.top();
+	m_fillColor = ScColorShade( QColor(0,0,0), 100 );
+	m_strokeColor = ScColorShade( QColor(0,0,0), 100 );
+	m_fillTrans = 1.0;
+	m_strokeTrans = 1.0;
+	m_fillRule = true;
+	m_fillMode = 1;
+	m_lineWidth = 1.0;
+	m_offset = 0;
+	m_array.clear();
+	m_lineEnd = Qt::SquareCap;
+	m_lineJoin = Qt::RoundJoin;
+	m_fillGradient = VGradientEx(VGradientEx::linear);
+	m_strokeGradient = VGradientEx(VGradientEx::linear);
+	m_matrix = QTransform();
+	m_pageTrans = QTransform();
+	// Path state
+	m_pathIsClosed = true;
+	m_drawingClosedPath = false;
+	// TODO : set proper values
+	m_deviceDimX = 0;
+	m_deviceDimY = 0;
+	m_deviceResX = 0;
+	m_deviceResY = 0;
+	clear();
+}
+
+ScPainterEx_Ps2::~ScPainterEx_Ps2()
+{
+}
+
+ScPainterExBase::ImageMode ScPainterEx_Ps2::imageMode()
+{
+	ImageMode imageMode;
+	if (m_options.hProfile && m_options.rgbToOutputImageTransform && m_options.cmykToOutputImageTransform)
+		imageMode = rawImages;
+	else if (m_colorMode == cmykMode)
+		imageMode = cmykImages;
+	else
+		imageMode = rgbImages;
+	return imageMode;
+}
+
+void ScPainterEx_Ps2::transformImage( QImage* image, uchar* data, int scan)
+{
+	int rgb, grey;
+	int imageWidth = image->width();
+	int imageHeight = image->height();
+
+	QRgb*  pscani;
+	uchar *pscand;
+
+	pscand = data;
+	for ( int j = 0; j < imageHeight; j++ )
+	{
+		pscani = (QRgb *) image->scanLine(j);
+		for (int i = 0; i < imageWidth; i++ )
+		{
+			rgb = pscani[i];
+			grey = qRound(0.3 * qRed(rgb)) + qRound(0.59 * qGreen(rgb)) + qRound(0.11 * qBlue(rgb));
+			pscand[i] = grey;
+		}
+		pscand += scan;
+	}
+
+}
+
+void ScPainterEx_Ps2::begin()
+{
+}
+
+void ScPainterEx_Ps2::end()
+{
+
+}
+
+void ScPainterEx_Ps2::clear()
+{
+
+}
+
+void ScPainterEx_Ps2::clear( ScColorShade &c )
+{
+
+}
+
+const QTransform ScPainterEx_Ps2::worldMatrix()
+{
+	return m_matrix;
+}
+
+void ScPainterEx_Ps2::setWorldMatrix( const QTransform &mat )
+{
+	m_matrix = mat;
+}
+
+void ScPainterEx_Ps2::transformPoint( const FPoint& in, FPoint& out )
+{
+	double x, y;
+	x = in.x() * m_matrix.m11() + in.y() * m_matrix.m21() + m_matrix.dx();
+	y = in.x() * m_matrix.m12() + in.y() * m_matrix.m22() + m_matrix.dy();
+	out.setX( x );
+	out.setY( y );
+}
+
+void ScPainterEx_Ps2::transformPoints( const FPoint* ArrayIn, FPoint* ArrayOut, uint length )
+{
+	for( uint i = 0; i < length; i++ )
+	{
+		transformPoint( ArrayIn[i], ArrayOut[i] );
+	}
+}
+
+void ScPainterEx_Ps2::translate( double x, double y )
+{
+	m_matrix.translate(x, y);
+}
+
+void ScPainterEx_Ps2::rotate( double r )
+{
+	m_matrix.rotate(r);
+}
+
+void ScPainterEx_Ps2::scale( double x, double y )
+{
+	m_matrix.scale(x, y);
+}
+
+void ScPainterEx_Ps2::moveTo( const double &x, const double &y )
+{
+	FPoint pp( x, y );
+	transformPoint( pp, pp );
+	m_stream << QString("%1 %2 moveto\n").arg(pp.x()).arg(pp.y());
+}
+
+void ScPainterEx_Ps2::lineTo( const double &x, const double &y )
+{
+	FPoint pp( x, y );
+	transformPoint( pp, pp );
+	m_stream << QString("%1 %2 lineto\n").arg(pp.x()).arg(pp.y());
+}
+
+void ScPainterEx_Ps2::curveTo( FPoint p1, FPoint p2, FPoint p3 )
+{
+	FPoint pps[3];
+	pps[0].setXY( p1.x(), p1.y() );
+	pps[1].setXY( p2.x(), p2.y() );
+	pps[2].setXY( p3.x(), p3.y() );
+	transformPoints( pps, pps, 3 );
+	m_stream << QString("%1 %2 %3 %4 %5 %6 curveto\n").arg(pps[0].x()).arg(pps[0].y()).arg(pps[1].x()).arg(pps[1].y()).arg(pps[2].x()).arg(pps[2].y());
+}
+
+void ScPainterEx_Ps2::newPath()
+{
+   m_stream << "newpath\n";
+   //pathIsClosed = false;
+}
+
+void ScPainterEx_Ps2::closePath()
+{
+	m_stream << "closepath\n";
+	m_pathIsClosed = true;
+}
+
+void ScPainterEx_Ps2::setFillRule( bool fillRule )
+{
+	m_fillRule = fillRule;
+}
+
+void ScPainterEx_Ps2::setFillMode( int fill )
+{
+	m_fillMode = fill;
+}
+
+void ScPainterEx_Ps2::setStrokeMode( int stroke )
+{
+	m_strokeMode = stroke;
+}
+
+void ScPainterEx_Ps2::setGradient(VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew)
+{
+	m_fillGradient.setType(mode);
+	m_fillGradient.setOrigin(orig);
+	m_fillGradient.setVector(vec);
+	m_fillGradient.setFocalPoint(foc);
+
+	m_strokeGradient.setType(mode);
+	m_strokeGradient.setOrigin(orig);
+	m_strokeGradient.setVector(vec);
+	m_strokeGradient.setFocalPoint(foc);;
+}
+
+void ScPainterEx_Ps2::setPattern(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY)
+{
+	m_pattern = pattern;
+	m_patternScaleX = scaleX / 100.0;
+	m_patternScaleY = scaleY / 100.0;
+	m_patternOffsetX = offsetX;
+	m_patternOffsetY = offsetY;
+	m_patternRotation = rotation;
+	m_patternSkewX   = skewX;
+	m_patternSkewY   = skewY;
+	m_patternMirrorX = mirrorX;
+	m_patternMirrorY = mirrorY;
+}
+
+void ScPainterEx_Ps2::fillTextPath()
+{
+	drawVPath( 0 );
+}
+
+void ScPainterEx_Ps2::strokeTextPath()
+{
+	if( m_lineWidth == 0 )
+		return;
+	drawVPath( 1 );
+}
+
+void ScPainterEx_Ps2::fillPath()
+{
+	if(!m_pathIsClosed)
+		closePath();
+	if( m_fillMode != 0)
+		drawVPath( 0 );
+}
+
+void ScPainterEx_Ps2::strokePath()
+{
+	if( m_lineWidth == 0 )
+		return;
+	save();
+	if(!m_pathIsClosed)
+		closePath();
+	drawVPath( 1 );
+	restore();
+}
+
+ScColorShade ScPainterEx_Ps2::pen()
+{
+	return m_strokeColor;
+}
+
+ScColorShade ScPainterEx_Ps2::brush()
+{
+	return m_fillColor;
+}
+
+void ScPainterEx_Ps2::setPen( const ScColorShade &c )
+{
+	m_strokeColor = c;
+}
+
+void ScPainterEx_Ps2::setPen( const ScColorShade &c, double w, Qt::PenStyle st, Qt::PenCapStyle ca, Qt::PenJoinStyle jo )
+{
+	m_offset = 0;
+	m_strokeColor = c;
+	m_lineWidth = w;
+	m_lineEnd = ca;
+	m_lineJoin = jo;
+	double Dt = qMax(2*w, 1.0);
+	double Da = qMax(6*w, 1.0);
+	m_array.clear();
+	if (st == Qt::DashLine)
+		m_array << Da << Dt;
+	else if (st == Qt::DotLine)
+		m_array << Dt;
+	else if (st == Qt::DashDotLine)
+		m_array << Da << Dt << Dt << Dt;
+	else if (st == Qt::DashDotDotLine)
+		m_array << Da << Dt << Dt << Dt << Dt << Dt; 
+}
+
+void ScPainterEx_Ps2::setLineWidth( double w )
+{
+	m_lineWidth = w;
+}
+
+void ScPainterEx_Ps2::setPenOpacity( double op )
+{
+	m_strokeTrans = op;
+}
+
+void ScPainterEx_Ps2::setDash(const QVector<double>& array, double ofs)
+{
+	m_array = array;
+	m_offset = ofs;
+}
+
+void ScPainterEx_Ps2::setBrush( const ScColorShade &c )
+{
+	m_fillColor = c;
+}
+
+void ScPainterEx_Ps2::setBrushOpacity( double op )
+{
+	m_fillTrans = op;
+}
+
+void ScPainterEx_Ps2::setOpacity( double op )
+{
+	m_fillTrans = op;
+	m_strokeTrans = op;
+}
+
+void ScPainterEx_Ps2::setFont( const QFont &f)
+{
+	m_font = f;
+}
+
+QFont ScPainterEx_Ps2::font()
+{
+	return m_font;
+}
+
+void ScPainterEx_Ps2::save()
+{
+	m_stack.push( m_matrix );
+	m_stream << "gsave\n";
+}
+
+void ScPainterEx_Ps2::restore()
+{
+	m_matrix = m_stack.pop();
+	m_stream << "grestore\n";
+}
+
+void ScPainterEx_Ps2::setRasterOp( int   )
+{
+}
+
+void ScPainterEx_Ps2::drawVPath( int mode )
+{
+	save();
+	if (mode == 0)
+	{
+		if (m_fillMode == ScPainterExBase::Gradient)
+			drawGradient( m_fillGradient );
+		else
+			putColor( m_fillColor, true );
+	}
+	else
+	{
+		double m11 = m_matrix.m11();
+		double m12 = m_matrix.m12();
+		double m21 = m_matrix.m21();
+		double m22 = m_matrix.m22();
+		double norm2 = m11 * m11 + m12 * m12 + m21 * m21 + m22 * m22;
+		double penScale = sqrt(norm2 /2.0);
+		double penWidth = (int) (m_lineWidth * penScale);
+		m_stream << QString("%1 setlinewidth\n").arg(penWidth);
+
+		m_stream << "[";
+		for( int i = 0; i < m_array.count();++ i )
+		{
+			m_stream << QString("%1").arg(m_array[i]) << " ";
+		}
+		m_stream << "]";
+		m_stream << " 0 setdash\n";
+
+		if( m_lineEnd == Qt::RoundCap )
+			m_stream << "1 setlinecap\n";
+		else if( m_lineEnd == Qt::SquareCap )
+			m_stream << "2 setlinecap\n";
+		else if( m_lineEnd == Qt::FlatCap )
+			m_stream << "0 setlinecap\n";
+		else
+			m_stream << "0 setlinecap\n";
+
+		if( m_lineJoin == Qt::RoundJoin )
+			m_stream << "1 setlinejoin\n";
+		else if( m_lineJoin == Qt::BevelJoin )
+			m_stream << "2 setlinejoin\n";
+		else if( m_lineJoin == Qt::MiterJoin )
+			m_stream << "0 setlinejoin\n";
+		else
+			m_stream << "0 setlinejoin\n";
+
+		putColor(m_strokeColor, false);
+	}
+	restore();
+}
+
+void ScPainterEx_Ps2::setClipPath()
+{
+	//TODO eoclip or clip?
+	m_stream << "clip newpath\n";
+	m_clipBBox = m_pathBBox;
+}
+
+void ScPainterEx_Ps2::putColor( ScColorShade& colorShade, bool doFill )
+{
+	ColorMode colorMode = m_colorMode;
+	int r = 0, g = 0, b = 0, gray = 0;
+	int c = 0, m = 0, y = 0, k = 0;
+	if ( m_options.toGray )
+	{
+		RGBColor rgb;
+		ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
+		rgb.getValues(r, g, b);
+		gray = qRound(0.3 * r + 0.59 * g + 0.11 * b);
+		if ( doFill && m_fillRule )
+			m_stream << QString("%1 setgray eofill\n").arg(gray/255.0);
+		else if ( doFill )
+			m_stream << QString("%1 setgray fill\n").arg(gray/255.0);
+		else
+			m_stream << QString("%1 setgray stroke\n").arg(gray/255.0);
+		return;
+	}
+	else if ( m_options.hProfile && m_options.rgbToOutputColorTransform && m_options.cmykToOutputColorTransform)
+	{
+		unsigned long colorIn[4];
+		unsigned long colorOut[4];
+		ScColorTransform cmsTranform = NULL;
+		if( colorShade.color.getColorModel() == colorModelRGB )
+		{
+			RGBColor rgb;
+			ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
+			colorIn[0] = rgb.r;
+			colorIn[1] = rgb.g;
+			colorIn[2] = rgb.b;
+			colorMode = rgbMode;
+			cmsTranform = m_options.rgbToOutputColorTransform;
+		} 
+		else
+		{
+			CMYKColor cmyk;
+			ScColorEngine::getShadeColorCMYK(colorShade.color, m_options.document, cmyk, colorShade.shade);
+			colorIn[0] = cmyk.c;
+			colorIn[1] = cmyk.m;
+			colorIn[2] = cmyk.y;
+			colorIn[3] = cmyk.k;
+			colorMode = cmykMode;
+			cmsTranform = m_options.cmykToOutputColorTransform;
+		}
+		cmsTranform.apply(colorIn, colorOut, 1 );
+		if (m_options.hProfile.colorSpace() == ColorSpace_Rgb)
+		{
+			r = colorOut[0] / 257;
+			g = colorOut[1] / 257;
+			b = colorOut[2] / 257;
+			colorMode = rgbMode;
+		}
+		else if (m_options.hProfile.colorSpace() == ColorSpace_Cmyk)
+		{
+			c = colorOut[0] / 257;
+			m = colorOut[1] / 257;
+			y = colorOut[2] / 257;
+			k = colorOut[3] / 257;
+			colorMode = cmykMode;
+		}
+	}
+	else if ( m_colorMode == rgbMode )
+	{
+		RGBColor rgb;
+		colorMode = rgbMode;
+		ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
+		rgb.getValues(r, g, b);
+	}
+	else if ( m_colorMode == cmykMode )
+	{
+		CMYKColor cmyk;
+		colorMode = cmykMode;
+		ScColorEngine::getShadeColorCMYK(colorShade.color, m_options.document, cmyk, colorShade.shade);
+		cmyk.getValues(c, m, y, k);
+	}
+
+	// Finally output to file
+	if ( colorMode == rgbMode )
+	{
+		if ( doFill && m_fillRule )
+			m_stream << QString("%1 %2 %3 setrgbcolor eofill\n").arg(r/255.0).arg(g/255.0).arg(b/255.0);
+		else if ( doFill )
+			m_stream << QString("%1 %2 %3 setrgbcolor fill\n").arg(r/255.0).arg(g/255.0).arg(b/255.0);
+		else
+			m_stream << QString("%1 %2 %3 setrgbcolor stroke\n").arg(r/255.0).arg(g/255.0).arg(b/255.0);			
+	}
+	else if ( colorMode == cmykMode )
+	{
+		QString colstr1 = QString("%1 %2 %3 %4 setcmykcolor").arg(c/255.0).arg(m/255.0).arg(y/255.0).arg(k/255.0);
+		if ( doFill && m_fillRule )
+			m_stream << colstr1 << " eofill\n";
+		else if ( doFill )
+			m_stream << colstr1 << " fill\n";
+		else
+			m_stream << colstr1 << " stroke\n";	
+	}
+}
+
+void ScPainterEx_Ps2::drawImage( ScImage *image, ScPainterExBase::ImageMode mode )
+{
+	bool rgbMode = (mode == ScPainterExBase::rgbImages);
+	bool rgbPicture = rgbMode || (mode == ScPainterExBase::rawImages && image->imgInfo.colorspace == ColorSpaceRGB);
+	bool cmykPicture = (mode == ScPainterExBase::cmykImages || (mode == ScPainterExBase::rawImages && image->imgInfo.colorspace == ColorSpaceCMYK)); 
+
+	if( rgbPicture )
+		drawRGBImage_ps2( image );
+	else if( cmykPicture )
+		drawCMYKImage_ps2( image );
+	else
+		qDebug( "ScPainterEx_Ps2::drawImage() : unknown image type" );
+}
+
+void ScPainterEx_Ps2::drawRGBImage_ps2( ScImage *image )
+{
+	save();
+	QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
+	m_stream << sc.arg(m_matrix.m11()).arg(m_matrix.m12()).arg(m_matrix.m21()).arg(m_matrix.m22()).arg(m_matrix.dx()).arg(m_matrix.dy());
+	m_stream << QString("%1 %2 scale\n").arg(image->width()).arg(image->height());
+	m_stream << "/DeviceRGB setcolorspace\n";
+	if (hasAlphaChannel(image))
+	{
+		QImage imgTemp = image->qImage();
+		QImage mask = imgTemp.createAlphaMask();
+		if (m_encoding == Ascii85Encoding)
+		{
+			m_stream << "currentfile /ASCII85Decode filter /ReusableStreamDecode filter\n";
+			writeRGBImageToStream_Ascii85(image);
+		}
+		else
+		{
+			m_stream << "currentfile /ASCIIHexDecode filter /ReusableStreamDecode filter\n";
+			writeRGBImageToStream_AsciiHex(image);
+		}
+		m_stream << "/myImage exch def\n";
+		m_stream << "currentfile /ASCIIHexDecode filter /ReusableStreamDecode filter\n";
+		writeMaskToStream(&mask);
+		m_stream << "/myMask exch def\n";
+		m_stream << QString("<<\n");
+		m_stream << QString("    /PaintType   1\n");
+		m_stream << QString("    /PatternType 1\n");
+		m_stream << QString("    /TilingType  3\n");
+		m_stream << QString("    /BBox        [ 0 0 1 1 ]\n");
+		m_stream << QString("    /XStep       2\n");
+		m_stream << QString("    /YStep       2\n");
+		m_stream << QString("    /PaintProc   {\n");
+		m_stream << QString("        pop\n");
+		m_stream << QString("        0 0 0 setrgbcolor\n");
+		m_stream << QString("        <<\n");
+		m_stream << QString("            /ImageType 1\n");
+		m_stream << QString("            /Width     %1\n").arg(image->width());
+		m_stream << QString("            /Height    %1\n").arg(image->height());
+		m_stream << QString("            /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
+		m_stream << QString("            /BitsPerComponent 8\n");
+		m_stream << QString("            /Decode [0 1 0 1 0 1]\n");
+		m_stream << QString("            /DataSource myImage\n");
+		m_stream << QString("        >>\n");
+		m_stream << QString("        image\n");
+		m_stream << QString("    }\n");
+		m_stream << QString(">> matrix makepattern setpattern\n");
+		m_stream << QString("<<\n");
+		m_stream << QString("    /ImageType 1\n");
+		m_stream << QString("    /Width %1 \n").arg(image->width());
+		m_stream << QString("    /Height %1 \n").arg(image->height());
+		m_stream << QString("    /BitsPerComponent 1\n");
+		m_stream << QString("    /Decode [1 0]\n");
+		m_stream << QString("    /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
+		m_stream << QString("    /DataSource myMask\n");
+		m_stream << QString(">>\n");
+		m_stream << QString("imagemask\n");
+	}
+	else
+	{
+		m_stream << QString("<<\n");
+		m_stream << QString("    /ImageType 1\n");
+		m_stream << QString("    /Width %1\n").arg(image->width());
+		m_stream << QString("    /Height %1\n").arg(image->height());
+		m_stream << QString("    /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
+		m_stream << QString("    /Decode [0 1 0 1 0 1]\n");
+		m_stream << QString("    /BitsPerComponent 8\n");
+		//TODO case where compression is available
+		if (m_encoding == Ascii85Encoding)
+		{
+			m_stream << QString("    /DataSource currentfile /ASCII85Decode filter\n");
+			m_stream << QString(">>\n");
+			m_stream << "image\n";
+			writeRGBImageToStream_Ascii85(image);
+		}
+		else
+		{
+			m_stream << QString("    /DataSource currentfile /ASCIIHexDecode filter\n");
+			m_stream << QString(">>\n");
+			m_stream << "image\n";
+			writeRGBImageToStream_AsciiHex(image);
+		}
+	}
+	restore();
+}
+
+void ScPainterEx_Ps2::drawCMYKImage_ps2( ScImage *image )
+{
+	save();
+	QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
+	m_stream << sc.arg(m_matrix.m11()).arg(m_matrix.m12()).arg(m_matrix.m21()).arg(m_matrix.m22()).arg(m_matrix.dx()).arg(m_matrix.dy());
+	m_stream << QString("%1 %2 scale\n").arg(image->width()).arg(image->height());
+	m_stream << "/DeviceCMYK setcolorspace\n";
+	// TODO case where image have a mask
+	bool haveMask = false;
+	if (haveMask)
+	{
+
+	}
+	else
+	{
+		m_stream << "<<\n";
+		m_stream << QString("    /ImageType 1\n");
+		m_stream << QString("    /Width %1\n").arg(image->width());
+		m_stream << QString("    /Height %1\n").arg(image->height());
+		m_stream << QString("    /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
+		m_stream << QString("    /Decode [0 1 0 1 0 1 0 1]\n");
+		m_stream << QString("    /BitsPerComponent 8\n");
+		//TODO case where compression is available
+		if (m_encoding == Ascii85Encoding)
+		{
+			m_stream << QString("    /DataSource currentfile /ASCII85Decode filter\n");
+			m_stream << QString(">>\n");
+			m_stream << "image\n";
+			writeCMYKImageToStream_Ascii85(image);
+		}
+		else
+		{
+			m_stream << QString("    /DataSource currentfile /ASCIIHexDecode filter\n");
+			m_stream << QString(">>\n");
+			m_stream << "image\n";
+			writeCMYKImageToStream_AsciiHex(image);
+		}
+	}
+	restore();
+}
+
+bool ScPainterEx_Ps2::hasAlphaChannel( ScImage* image )
+{
+	bool   hasAlpha = false;
+	int    width = image->width();
+	int    height = image->height();
+	for( int y = 0; y < height; y++ )
+	{
+		QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
+		for( int x = 0; x < width; ++x )
+		{
+			if( qAlpha(*imageBits) != 255 )
+			{
+				hasAlpha = true;
+				break;
+			}
+			imageBits++;
+		}
+	}
+	return hasAlpha;
+}
+
+void ScPainterEx_Ps2::writeMaskToStream( QImage* image )
+{
+	int    length = 0;
+	unsigned char bits;
+	int    width = image->width() / 8;
+	int    height = image->height();
+	if ((image->width() % 8) != 0)
+		width++;
+	for( int y = 0; y < height; ++y )
+	{
+		unsigned char* imageBits = image->scanLine(y);
+		for( int x = 0; x < width; x++ )
+		{
+			length++;
+			bits = imageBits[x];
+			m_stream << toHex(bits);
+			if ( (length % 49) == 0 )
+				m_stream << "\n";
+		}
+	}
+	m_stream << "\n>\n";
+}
+
+void ScPainterEx_Ps2::writeRGBImageToStream_Ascii85( ScImage* image )
+{
+	int  cindex;
+	int  pending = 0, written = 0;
+	bool allZero  = true;
+	unsigned char  four_tuple[4];
+	const char* ascii85;
+	quint32 value;
+
+	int width = image->width();
+	int height = image->height();
+	for( int y = 0; y < height; ++y )
+	{
+		QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
+		for( int x = 0; x < width; ++x )
+		{
+			cindex = 0;
+			while (cindex < 3)
+			{
+				if (cindex == 0)
+					four_tuple[pending++] = (uchar) qRed(*imageBits);
+				else if (cindex == 1)
+					four_tuple[pending++] = (uchar) qGreen(*imageBits);
+				else if (cindex == 2)
+					four_tuple[pending++] = (uchar) qBlue(*imageBits);
+				if (pending == 4) 
+				{
+					value   = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
+					ascii85 = toAscii85(value, allZero);
+					if (allZero)
+						m_stream << "z";
+					else
+						m_stream << ascii85;
+					written += ((allZero) ? 1 : 5);
+					if (written > 75)
+					{
+						m_stream << "\n";
+						written = 0;
+					}
+					pending = 0;
+				}
+				++cindex;
+			}
+			
+		}
+	}
+	if (pending) 
+	{
+		unsigned char five_tuple[6];
+		memset (four_tuple + pending, 0, 4 - pending);
+		value   = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
+		ascii85 = toAscii85(value, allZero);
+		memcpy (five_tuple, ascii85, 5);
+		five_tuple[pending + 1] = 0;
+		m_stream << (const char*) five_tuple;
+	}
+	m_stream << "~>\n";
+}
+
+void ScPainterEx_Ps2::writeRGBImageToStream_AsciiHex ( ScImage* image )
+{
+	int  length = 0;
+	int  width = image->width();
+	int  height = image->height();
+	for( int y = 0; y < height; ++y )
+	{
+		QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
+		for( int x = 0; x < width; ++x )
+		{
+			length++;
+			uchar r = (uchar) qRed(*imageBits);
+			m_stream << toHex(r);
+			uchar g = (uchar) qGreen(*imageBits);
+			m_stream << toHex(g);
+			uchar b = (uchar) qBlue(*imageBits);
+			m_stream << toHex(b);
+			if ( (length % 17) == 0 )
+				m_stream << "\n";
+			imageBits++;
+		}
+	}
+	m_stream << "\n>\n";
+}
+
+void ScPainterEx_Ps2::writeCMYKImageToStream_Ascii85( ScImage* image )
+{
+	int  written = 0;
+	bool allZero  = true;
+	unsigned char  four_tuple[4];
+	const char* ascii85;
+	quint32 value;
+
+	int width = image->width();
+	int height = image->height();
+	for( int y = 0; y < height; y++ )
+	{
+		QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
+		for( int x = 0; x < width; x++ )
+		{
+			four_tuple[0] = (uchar) qRed(*imageBits);
+			four_tuple[1] = (uchar) qGreen(*imageBits);
+			four_tuple[2] = (uchar) qBlue(*imageBits);
+			four_tuple[3] = (uchar) qAlpha(*imageBits);
+			value   = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
+			ascii85 = toAscii85(value, allZero);
+			if (allZero)
+				m_stream << "z";
+			else
+				m_stream << ascii85;
+			written += ((allZero) ? 1 : 5);
+			if (written > 75)
+			{
+				m_stream << "\n";
+				written = 0;
+			}
+			imageBits++;
+		}
+	}
+	m_stream << "~>\n";
+}
+
+void ScPainterEx_Ps2::writeCMYKImageToStream_AsciiHex( ScImage* image )
+{
+	int length = 0;
+	int width = image->width();
+	int height = image->height();
+	for( int y = 0; y < height; ++y )
+	{
+		QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
+		for( int x = 0; x < width; ++x )
+		{
+			length++;
+			uchar c = (uchar) qRed(*imageBits);
+			m_stream << toHex(c);
+			uchar m = (uchar) qGreen(*imageBits);
+			m_stream << toHex(m);
+			uchar y = (uchar) qBlue(*imageBits);
+			m_stream << toHex(y);
+			uchar k = (uchar) qAlpha(*imageBits);
+			m_stream << toHex(k);
+			if ( (length % 13) == 0 )
+				m_stream << "\n";
+			imageBits++;
+		}
+	}
+	m_stream << "\n>\n";
+}
+
+void ScPainterEx_Ps2::setupPolygon(FPointArray *points, bool closed)
+{
+	bool nPath = true;
+	FPoint np, np1, np2, np3;
+	if (points->size() > 3)
+	{
+		newPath();
+		for (uint poi=0; poi<points->size()-3; poi += 4)
+		{
+			if (points->point(poi).x() > 900000)
+			{
+				nPath = true;
+				continue;
+			}
+			if (nPath)
+			{
+				np = points->point(poi);
+				// TODO startfigure needed?
+				moveTo( np.x(), np.y() );
+				nPath = false;
+			}
+			np = points->point(poi);
+			np1 = points->point(poi+1);
+			np2 = points->point(poi+3);
+			np3 = points->point(poi+2);
+			if ((np == np1) && (np2 == np3))
+				lineTo( np3.x(), np3.y() );
+			else
+				curveTo(np1, np2, np3);
+		}
+		if (closed)
+		{
+			closePath();
+			m_drawingClosedPath = true;
+		}
+	}
+	getPathBoundingBox( points, m_pathBBox );
+}
+
+void ScPainterEx_Ps2::drawPolygon()
+{
+	fillPath();
+}
+
+void ScPainterEx_Ps2::drawPolyLine()
+{
+	strokePath();
+}
+
+void ScPainterEx_Ps2::drawLine(FPoint start, FPoint end)
+{
+	newPath();
+	moveTo(start.x(), start.y());
+	lineTo(end.x(), end.y());
+	strokePath();
+}
+
+void ScPainterEx_Ps2::drawRect(double x, double y, double w, double h)
+{
+	newPath();
+	moveTo( x, y );
+	lineTo( x+w, y );
+	lineTo( x+w, y+h );
+	lineTo( x, y+h );
+	lineTo( x, y );
+	closePath();
+	m_drawingClosedPath = true;
+	fillPath();
+	strokePath();
+}
+
+void ScPainterEx_Ps2::drawGradient( VGradientEx& gradient )
+{
+	QRect clipPathRect;
+	save();
+	//setClipPath();
+	m_stream << "clip\n";
+	m_clipBBox = m_pathBBox;
+	if ( gradient.type() == VGradientEx::linear )
+		drawLinearGradient( gradient, m_clipBBox );
+	else if ( gradient.type() == VGradientEx::radial )
+		drawCircularGradient( gradient, m_clipBBox );
+	restore();
+}
+
+void ScPainterEx_Ps2::drawLinearGradient( VGradientEx& gradient, const QRect& rect )
+{
+	if (m_colorMode == cmykMode)
+		drawLinearGradient_CMYK(gradient, rect);
+	else
+		drawLinearGradient_RGB(gradient, rect);
+}
+
+void ScPainterEx_Ps2::drawLinearGradient_RGB( VGradientEx& gradient, const QRect& rect )
+{
+	int r1, g1, b1;
+	int r2, g2, b2;
+	double cosa, sina;
+	double ramp1, ramp2;
+	double scale1, scale2;
+	double length, scale;
+	double x1, y1, x2, y2, dx, dy;
+	int clipBoxWidth, clipBoxHeight, maxDim;
+	QList<VColorStopEx*> colorStops = gradient.colorStops();
+	VColorStopEx stop1( *colorStops[0] );
+	VColorStopEx stop2( *colorStops[0] );
+	RGBColor rgb;
+	FPoint p1, p2;
+	QColor color;
+
+	if ( gradient.Stops() < 2 ) 
+		return;
+
+	clipBoxWidth = rect.width();
+	clipBoxHeight = rect.height();
+	maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
+	if ( maxDim <= 0 ) return;
+	
+	scale1 = sqrt( m_matrix.m11() * m_matrix.m11() + m_matrix.m12() * m_matrix.m12() );
+	scale2 = sqrt( m_matrix.m21() * m_matrix.m21() + m_matrix.m22() * m_matrix.m22() );
+
+	x1 = m_matrix.dx() + gradient.origin().x() * m_matrix.m11();
+	y1 = m_matrix.dy() + gradient.origin().y() * m_matrix.m22();
+	x2 = m_matrix.dx() + gradient.vector().x() * m_matrix.m11();
+	y2 = m_matrix.dy() + gradient.vector().y() * m_matrix.m22();
+	p1.setXY( x1, y1 );
+	p2.setXY( x2, y2 );
+
+	dx = ( p2.x() - p1.x() );
+	dy = ( p2.y() - p1.y() );
+	length = sqrt(( dx * dx + dy * dy ));
+	if ( length == 0.0 )
+		scale = 1.0;
+	else
+		scale = 1.0 / length;
+	cosa = dx * scale;
+	sina = dy * scale;
+
+	QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
+	m_stream << sc.arg(cosa).arg(sina).arg(-sina).arg(cosa).arg(x1).arg(y1);
+
+	ramp1 = stop1.rampPoint;
+	ScColorEngine::getShadeColorRGB(stop1.color, m_options.document, rgb, stop1.shade);
+	rgb.getValues(r1, g1, b1);
+	m_stream << QString("%1 %2 %3 setrgbcolor fill\n").arg(r1/255.0).arg(g1/255.0).arg(b1/255.0);
+
+	for( uint index = 1; index < gradient.Stops(); index++)
+	{
+		stop2 = *colorStops[index];
+		ramp2 = stop2.rampPoint;
+		ScColorEngine::getShadeColorRGB(stop2.color, m_options.document, rgb, stop2.shade);
+		rgb.getValues(r2, g2, b2);
+		double xMin = length * ramp1;
+		double xMax = length * ramp2;
+
+		m_stream << QString("/x1 %1 def\n").arg(xMin);
+		m_stream << QString("/x2 %1 def\n").arg(xMax);
+		m_stream << QString("/r1 %1 def\n").arg(r1/255.0);
+		m_stream << QString("/g1 %1 def\n").arg(g1/255.0);
+		m_stream << QString("/b1 %1 def\n").arg(b1/255.0);
+		m_stream << QString("/r2 %1 def\n").arg(r2/255.0);
+		m_stream << QString("/g2 %1 def\n").arg(g2/255.0);
+		m_stream << QString("/b2 %1 def\n").arg(b2/255.0);
+		m_stream << QString("/maxd %1 def\n").arg(maxDim);
+		m_stream << QString("/mmaxd %1 def\n").arg(-maxDim/2.0);
+		m_stream << "r1 r2 sub abs 255 mul /dr exch def\n";
+		m_stream << "g1 g2 sub abs 255 mul /dg exch def\n";
+		m_stream << "b1 b2 sub abs 255 mul /db exch def\n";
+		m_stream << "dr dg add db add /colsteps exch def\n";
+		m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
+		m_stream << "x2 x1 sub colsteps div /xinc exch def\n";
+		m_stream << "xinc 2 mul /xinc2 exch def\n";
+		m_stream << "x2 xinc2 lt { /xinc2 x2 def } if\n";
+		m_stream << "r2 r1 sub colsteps div /rinc exch def\n";
+		m_stream << "g2 g1 sub colsteps div /ginc exch def\n";
+		m_stream << "b2 b1 sub colsteps div /binc exch def\n";
+		//m_stream << "r1 g1 b1 setrgbcolor\n";
+		//m_stream << "0 mmaxd maxd maxd rectfill\n";
+		m_stream << "0 1 colsteps\n";
+		m_stream << "{\n";
+		m_stream << "    r1 g1 b1 setrgbcolor\n";
+		m_stream << "    x1 mmaxd xinc2 maxd rectfill\n"; //rectfill is a ps2 operator
+		m_stream << "    x1 xinc add /x1 exch def\n";
+		m_stream << "    r1 rinc add /r1 exch def\n";
+		m_stream << "    g1 ginc add /g1 exch def\n";
+		m_stream << "    b1 binc add /b1 exch def\n";
+		m_stream << "} for\n";
+		m_stream << "x2 mmaxd maxd maxd rectfill\n";
+
+		stop1 = stop2;
+		ramp1 = ramp2;
+		r1 = r2;
+		g1 = g2;
+		b1 = b2;
+	}
+}
+
+void ScPainterEx_Ps2::drawLinearGradient_CMYK( VGradientEx& gradient, const QRect& rect )
+{
+	int c1, m1, j1, n1;
+	int c2, m2, j2, n2;
+	double cosa, sina;
+	double ramp1, ramp2;
+	double scale1, scale2;
+	double length, scale;
+	double x1, y1, x2, y2, dx, dy;
+	int clipBoxWidth, clipBoxHeight, maxDim;
+	QList<VColorStopEx*> colorStops = gradient.colorStops();
+	VColorStopEx stop1( *colorStops[0] );
+	VColorStopEx stop2( *colorStops[0] );
+	CMYKColor cmyk;
+	FPoint p1, p2;
+	QColor color;
+
+	if ( gradient.Stops() < 2 ) 
+		return;
+
+	clipBoxWidth = rect.width();
+	clipBoxHeight = rect.height();
+	maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
+	if ( maxDim <= 0 ) return;
+	
+	scale1 = sqrt( m_matrix.m11() * m_matrix.m11() + m_matrix.m12() * m_matrix.m12() );
+	scale2 = sqrt( m_matrix.m21() * m_matrix.m21() + m_matrix.m22() * m_matrix.m22() );
+
+	x1 = m_matrix.dx() + gradient.origin().x() * m_matrix.m11();
+	y1 = m_matrix.dy() + gradient.origin().y() * m_matrix.m22();
+	x2 = m_matrix.dx() + gradient.vector().x() * m_matrix.m11();
+	y2 = m_matrix.dy() + gradient.vector().y() * m_matrix.m22();
+	p1.setXY( x1, y1 );
+	p2.setXY( x2, y2 );
+
+	dx = ( p2.x() - p1.x() );
+	dy = ( p2.y() - p1.y() );
+	length = sqrt(( dx * dx + dy * dy ));
+	if ( length == 0.0 )
+		scale = 1.0;
+	else
+		scale = 1.0 / length;
+	cosa = dx * scale;
+	sina = dy * scale;
+
+	QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
+	m_stream << sc.arg(cosa).arg(sina).arg(-sina).arg(cosa).arg(x1).arg(y1);
+
+	ramp1 = stop1.rampPoint;
+	ScColorEngine::getShadeColorCMYK(stop1.color, m_options.document, cmyk, stop1.shade);
+	cmyk.getValues(c1, m1, j1, n1);
+	m_stream << QString("/DeviceCMYK setcolorspace\n");
+	m_stream << QString("%1 %2 %3 %4 setcolor fill\n").arg(c1/255.0).arg(m1/255.0).arg(j1/255.0).arg(n1/255.0);
+
+	for( uint index = 1; index < gradient.Stops(); index++)
+	{
+		stop2 = *colorStops[index];
+		ramp2 = stop2.rampPoint;
+		ScColorEngine::getShadeColorCMYK(stop2.color, m_options.document, cmyk, stop2.shade);
+		cmyk.getValues(c2, m2, j2, n2);
+		double xMin = length * ramp1;
+		double xMax = length * ramp2;
+
+		m_stream << QString("/x1 %1 def\n").arg(xMin);
+		m_stream << QString("/x2 %1 def\n").arg(xMax);
+		m_stream << QString("/c1 %1 def\n").arg(c1/255.0);
+		m_stream << QString("/m1 %1 def\n").arg(m1/255.0);
+		m_stream << QString("/y1 %1 def\n").arg(j1/255.0);
+		m_stream << QString("/k1 %1 def\n").arg(n1/255.0);
+		m_stream << QString("/c2 %1 def\n").arg(c2/255.0);
+		m_stream << QString("/m2 %1 def\n").arg(m2/255.0);
+		m_stream << QString("/y2 %1 def\n").arg(j2/255.0);
+		m_stream << QString("/k2 %1 def\n").arg(n2/255.0);
+		m_stream << QString("/maxd %1 def\n").arg(maxDim);
+		m_stream << QString("/mmaxd %1 def\n").arg(-maxDim/2.0);
+		m_stream << "c1 c2 sub abs 255 mul /dc exch def\n";
+		m_stream << "m1 m2 sub abs 255 mul /dm exch def\n";
+		m_stream << "y1 y2 sub abs 255 mul /dy exch def\n";
+		m_stream << "k1 k2 sub abs 255 mul /dk exch def\n";
+		m_stream << "dc dm add dy add dk add /colsteps exch def\n";
+		m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
+		m_stream << "x2 x1 sub colsteps div /xinc exch def\n";
+		m_stream << "xinc 2 mul /xinc2 exch def\n";
+		m_stream << "x2 xinc2 lt { /xinc2 x2 def } if\n";
+		m_stream << "c2 c1 sub colsteps div /cinc exch def\n";
+		m_stream << "m2 m1 sub colsteps div /minc exch def\n";
+		m_stream << "y2 y1 sub colsteps div /yinc exch def\n";
+		m_stream << "k2 k1 sub colsteps div /kinc exch def\n";
+		//m_stream << "r1 g1 b1 setrgbcolor\n";
+		//m_stream << "0 mmaxd maxd maxd rectfill\n";
+		m_stream << "0 1 colsteps\n";
+		m_stream << "{\n";
+		m_stream << "    c1 m1 y1 k1 setcolor\n";
+		m_stream << "    x1 mmaxd xinc2 maxd rectfill\n"; //rectfill is a ps2 operator
+		m_stream << "    x1 xinc add /x1 exch def\n";
+		m_stream << "    c1 cinc add /c1 exch def\n";
+		m_stream << "    m1 minc add /m1 exch def\n";
+		m_stream << "    y1 yinc add /y1 exch def\n";
+		m_stream << "    k1 kinc add /k1 exch def\n";
+		m_stream << "} for\n";
+		m_stream << "x2 mmaxd maxd maxd rectfill\n";
+
+		stop1 = stop2;
+		ramp1 = ramp2;
+		c1 = c2;
+		m1 = m2;
+		j1 = j2;
+		n1 = n2;
+	}
+}
+
+void ScPainterEx_Ps2::drawCircularGradient( VGradientEx& gradient, const QRect& rect )
+{
+	if (m_colorMode == cmykMode)
+		drawCircularGradient_CMYK(gradient, rect);
+	else
+		drawCircularGradient_RGB(gradient, rect);
+}
+
+void ScPainterEx_Ps2::drawCircularGradient_RGB( VGradientEx& gradient, const QRect& rect )
+{
+	int r1, g1, b1;
+	int r2, g2, b2;
+	double ramp1, ramp2;
+	double scale1, scale2;
+	int clipBoxWidth, clipBoxHeight, maxDim;
+	QList<VColorStopEx*> colorStops = gradient.colorStops();
+	VColorStopEx stop1( *colorStops[gradient.Stops() - 1] );
+	VColorStopEx stop2( *colorStops[gradient.Stops() - 1] );
+	RGBColor rgb;
+	QColor color;
+
+	clipBoxWidth = rect.width();
+	clipBoxHeight = rect.height();
+	maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
+	if ( maxDim <= 0 ) return;
+
+	scale1 = sqrt( m_matrix.m11() * m_matrix.m11() + m_matrix.m21() * m_matrix.m21() );
+	scale2 = sqrt( m_matrix.m12() * m_matrix.m12() + m_matrix.m22() * m_matrix.m22() );
+
+	FPoint pc( gradient.origin().x(), gradient.origin().y() );
+	FPoint pcz( gradient.origin().x(), gradient.origin().y() );
+	FPoint pf( gradient.focalPoint().x(), gradient.focalPoint().y() );
+	FPoint pfz( gradient.focalPoint().x(), gradient.focalPoint().y() );
+	FPoint pv( gradient.vector().x(), gradient.vector().y() );
+	transformPoint( pc, pc );
+	transformPoint( pf, pf );
+	transformPoint( pv, pv );
+	transformPoint( pcz, pcz );
+	transformPoint( pfz, pfz );
+	double cx = pcz.x();
+	double cy = pcz.y();
+	double rad = sqrt( pow(pv.x() -pc.x(), 2) + pow(pv.y() - pc.y(), 2) );
+
+	ramp2 = stop2.rampPoint;
+	ScColorEngine::getShadeColorRGB(stop2.color, m_options.document, rgb, stop2.shade);
+	rgb.getValues(r2, g2, b2);
+	m_stream << QString("%1 %2 %3 setrgbcolor fill\n").arg(r2).arg(g2).arg(b2);
+	if ( gradient.Stops() < 2 ) return;
+
+	for( int index = gradient.Stops() - 2; index >= 0; index--)
+	{
+		stop1 = *colorStops[index];
+		ramp1 = stop1.rampPoint;
+		ScColorEngine::getShadeColorRGB(stop1.color, m_options.document, rgb, stop1.shade);
+		rgb.getValues(r1, g1, b1);
+		int radMax = qRound(rad * ramp2);
+		int radMin = qRound(rad * ramp1);
+		
+		m_stream << QString("/rad1 %1 def\n").arg(radMax);
+		m_stream << QString("/rad2 %1 def\n").arg(radMin);
+		m_stream << QString("/circx %1 def\n").arg(cx);
+		m_stream << QString("/circy %1 def\n").arg(cy);
+		m_stream << QString("/r1 %1 def\n").arg(r1/255.0);
+		m_stream << QString("/g1 %1 def\n").arg(g1/255.0);
+		m_stream << QString("/b1 %1 def\n").arg(b1/255.0);
+		m_stream << QString("/r2 %1 def\n").arg(r2/255.0);
+		m_stream << QString("/g2 %1 def\n").arg(g2/255.0);
+		m_stream << QString("/b2 %1 def\n").arg(b2/255.0);
+		m_stream << "r1 r2 sub abs 255 mul /dr exch def\n";
+		m_stream << "g1 g2 sub abs 255 mul /dg exch def\n";
+		m_stream << "b1 b2 sub abs 255 mul /db exch def\n";
+		m_stream << "dr dg add db add /colsteps exch def\n";
+		m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
+		m_stream << "rad2 rad1 sub colsteps div /radinc exch def\n";
+		m_stream << "r1 r2 sub colsteps div /rinc exch def\n";
+		m_stream << "g1 g2 sub colsteps div /ginc exch def\n";
+		m_stream << "b1 b2 sub colsteps div /binc exch def\n";
+		m_stream << "0 1 colsteps\n";
+		m_stream << "{\n";
+		m_stream << "    r2 g2 b2 setrgbcolor\n";
+		m_stream << "    circx circy rad1 0 360 arc closepath fill\n"; 
+		m_stream << "    rad1 radinc add /rad1 exch def\n";
+		m_stream << "    r2 rinc add /r2 exch def\n";
+		m_stream << "    g2 ginc add /g2 exch def\n";
+		m_stream << "    b2 binc add /b2 exch def\n";
+		m_stream << "} for\n";
+
+		stop2 = stop1;
+		ramp2 = ramp1;
+		r2 = r1;
+		g2 = g1;
+		b2 = b1;
+	}
+}
+
+void ScPainterEx_Ps2::drawCircularGradient_CMYK( VGradientEx& gradient, const QRect& rect )
+{
+	int c1, m1, y1, k1;
+	int c2, m2, y2, k2;
+	double ramp1, ramp2;
+	double scale1, scale2;
+	int clipBoxWidth, clipBoxHeight, maxDim;
+	QList<VColorStopEx*> colorStops = gradient.colorStops();
+	VColorStopEx stop1( *colorStops[gradient.Stops() - 1] );
+	VColorStopEx stop2( *colorStops[gradient.Stops() - 1] );
+	CMYKColor cmyk;
+	QColor color;
+
+	clipBoxWidth = rect.width();
+	clipBoxHeight = rect.height();
+	maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
+	if ( maxDim <= 0 ) return;
+
+	scale1 = sqrt( m_matrix.m11() * m_matrix.m11() + m_matrix.m21() * m_matrix.m21() );
+	scale2 = sqrt( m_matrix.m12() * m_matrix.m12() + m_matrix.m22() * m_matrix.m22() );
+
+	FPoint pc( gradient.origin().x(), gradient.origin().y() );
+	FPoint pcz( gradient.origin().x(), gradient.origin().y() );
+	FPoint pf( gradient.focalPoint().x(), gradient.focalPoint().y() );
+	FPoint pfz( gradient.focalPoint().x(), gradient.focalPoint().y() );
+	FPoint pv( gradient.vector().x(), gradient.vector().y() );
+	transformPoint( pc, pc );
+	transformPoint( pf, pf );
+	transformPoint( pv, pv );
+	transformPoint( pcz, pcz );
+	transformPoint( pfz, pfz );
+	double cx = pcz.x();
+	double cy = pcz.y();
+	double rad = sqrt( pow(pv.x() -pc.x(), 2) + pow(pv.y() - pc.y(), 2) );
+
+	ramp2 = stop2.rampPoint;
+	ScColorEngine::getShadeColorCMYK(stop2.color, m_options.document, cmyk, stop2.shade);
+	cmyk.getValues(c2, m2, y2, k2);
+	m_stream << QString("/DeviceCMYK setcolorspace\n");
+	m_stream << QString("%0 %1 %2 %3 setcolor fill\n").arg(c2).arg(m2).arg(y2).arg(k2);
+	if ( gradient.Stops() < 2 ) return;
+
+	for( int index = gradient.Stops() - 2; index >= 0; index--)
+	{
+		stop1 = *colorStops[index];
+		ramp1 = stop1.rampPoint;
+		ScColorEngine::getShadeColorCMYK(stop1.color, m_options.document, cmyk, stop1.shade);
+		cmyk.getValues(c1, m1, y1, k1);
+		int radMax = qRound(rad * ramp2);
+		int radMin = qRound(rad * ramp1);
+		
+		m_stream << QString("/rad1 %1 def\n").arg(radMax);
+		m_stream << QString("/rad2 %1 def\n").arg(radMin);
+		m_stream << QString("/circx %1 def\n").arg(cx);
+		m_stream << QString("/circy %1 def\n").arg(cy);
+		m_stream << QString("/c1 %1 def\n").arg(c1/255.0);
+		m_stream << QString("/m1 %1 def\n").arg(m1/255.0);
+		m_stream << QString("/y1 %1 def\n").arg(y1/255.0);
+		m_stream << QString("/k1 %1 def\n").arg(k1/255.0);
+		m_stream << QString("/c2 %1 def\n").arg(c2/255.0);
+		m_stream << QString("/m2 %1 def\n").arg(m2/255.0);
+		m_stream << QString("/y2 %1 def\n").arg(y2/255.0);
+		m_stream << QString("/k2 %1 def\n").arg(k2/255.0);
+		m_stream << "c1 c2 sub abs 255 mul /dc exch def\n";
+		m_stream << "m1 m2 sub abs 255 mul /dm exch def\n";
+		m_stream << "y1 y2 sub abs 255 mul /dy exch def\n";
+		m_stream << "k1 k2 sub abs 255 mul /dk exch def\n";
+		m_stream << "dc dm add dy add dk add /colsteps exch def\n";
+		m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
+		m_stream << "rad2 rad1 sub colsteps div /radinc exch def\n";
+		m_stream << "c1 c2 sub colsteps div /cinc exch def\n";
+		m_stream << "m1 m2 sub colsteps div /minc exch def\n";
+		m_stream << "y1 y2 sub colsteps div /yinc exch def\n";
+		m_stream << "k1 k2 sub colsteps div /kinc exch def\n";
+		m_stream << "0 1 colsteps\n";
+		m_stream << "{\n";
+		m_stream << "    c2 m2 y2 k2 setcolor\n";
+		m_stream << "    circx circy rad1 0 360 arc closepath fill\n"; 
+		m_stream << "    rad1 radinc add /rad1 exch def\n";
+		m_stream << "    c2 cinc add /c2 exch def\n";
+		m_stream << "    m2 minc add /m2 exch def\n";
+		m_stream << "    y2 yinc add /y2 exch def\n";
+		m_stream << "    k2 kinc add /k2 exch def\n";
+		m_stream << "} for\n";
+
+		stop2 = stop1;
+		ramp2 = ramp1;
+		c2 = c1;
+		m2 = m1;
+		y2 = y1;
+		k2 = k1;
+	}
+}
+
+void ScPainterEx_Ps2::getPathBoundingBox( FPointArray* points, QRect& r )
+{
+	FPoint point;
+	double bottom = DBL_MAX, top   = DBL_MIN;
+	double left   = DBL_MAX, right = DBL_MIN;
+
+	r.setCoords(0, 0, 0, 0);
+
+	for( uint i = 0; i < points->size(); i++ )
+	{
+		point = points->point(i);
+		if( point.x() > 900000 )
+			continue;
+		transformPoint(point, point);
+		if( point.x() < left ) left = point.x();
+		if( point.x() > right ) right = point.x();
+		if( point.y() < bottom ) bottom = point.y();
+		if( point.y() > top ) top = point.y();
+	}
+	r.setCoords( qRound(left), qRound(bottom), qRound(right), qRound(top) );
+}
+

Modified: trunk/Scribus/scribus/scpainterex_ps2.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17263&path=/trunk/Scribus/scribus/scpainterex_ps2.h
==============================================================================
--- trunk/Scribus/scribus/scpainterex_ps2.h (original)
+++ trunk/Scribus/scribus/scpainterex_ps2.h Tue Jan 31 00:04:40 2012
@@ -107,8 +107,21 @@
 	virtual bool fillRule() { return m_fillRule; }
 	virtual void setFillMode( int fill );
 	virtual int  fillMode() { return m_fillMode; }
-	virtual void setGradient( VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc = FPoint(0,0));
-	virtual void setPattern ( ScPattern* pattern, QTransform& patternTransform );
+	virtual void setStrokeMode( int fill );
+	virtual int  strokeMode() { return m_strokeMode; }
+	virtual void setGradient( VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew);
+	virtual void setPattern(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY);
+
+	virtual void setMaskMode( int mask ) {};
+	virtual void setGradientMask(VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew) {};
+	virtual void setPatternMask(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY) {};
+
+	virtual void set4ColorGeometry(FPoint p1, FPoint p2, FPoint p3, FPoint p4, FPoint c1, FPoint c2, FPoint c3, FPoint c4) {};
+	virtual void set4ColorColors(const ScColorShade& col1, const ScColorShade& col2, const ScColorShade& col3, const ScColorShade& col4) {};
+	virtual void setDiamondGeometry(FPoint p1, FPoint p2, FPoint p3, FPoint p4, FPoint c1, FPoint c2, FPoint c3, FPoint c4, FPoint c5) {};
+	virtual void setMeshGradient(FPoint p1, FPoint p2, FPoint p3, FPoint p4, QList<QList<meshPoint> > meshArray) {};
+	virtual void setMeshGradient(FPoint p1, FPoint p2, FPoint p3, FPoint p4, QList<meshGradientPatch> meshPatches) {};
+
 	virtual void setClipPath();
 
 	virtual void drawImage( ScImage *image, ScPainterExBase::ImageMode mode );
@@ -142,6 +155,8 @@
 	virtual void restore();
 
 	virtual void setRasterOp( int op );
+	virtual void setBlendModeFill( int blendMode ) {};
+	virtual void setBlendModeStroke( int blendMode ) {};
 
 protected:
 
@@ -198,11 +213,22 @@
 	bool   m_fillRule;
 	int    m_fillMode;			// 0 = none, 1 = solid, 2 = gradient
 	int    m_gradientMode;		// 1 = linear, 2 = radial
+
+	double m_patternScaleX;
+	double m_patternScaleY;
+	double m_patternOffsetX;
+	double m_patternOffsetY;
+	double m_patternRotation;
+	double m_patternSkewX;
+	double m_patternSkewY;
+	bool   m_patternMirrorX;
+	bool   m_patternMirrorY;
+
 /* Stroking */
 	ScColorShade m_strokeColor;
 	double m_strokeTrans;
 	double m_lineWidth;
-
+	int    m_strokeMode;				// 0 = none, 1 = solid, 2 = gradient 3 = pattern
 /* Line End Style */
 	Qt::PenCapStyle m_lineEnd;
 /* Line Join Style */

Modified: trunk/Scribus/scribus/scpainterexbase.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17263&path=/trunk/Scribus/scribus/scpainterexbase.h
==============================================================================
--- trunk/Scribus/scribus/scpainterexbase.h (original)
+++ trunk/Scribus/scribus/scpainterexbase.h Tue Jan 31 00:04:40 2012
@@ -91,8 +91,21 @@
 	virtual bool fillRule()  = 0;
 	virtual void setFillMode( int fill ) = 0;
 	virtual int  fillMode() = 0;
-	virtual void setGradient( VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc = FPoint(0,0) ) = 0;
-	virtual void setPattern ( ScPattern* pattern, QTransform& patternTransform ) = 0;
+	virtual void setStrokeMode( int stroke ) = 0;
+	virtual int  strokeMode() = 0;
+	virtual void setGradient( VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew ) = 0;
+	virtual void setPattern(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY) = 0;
+
+	virtual void setMaskMode( int mask ) = 0;
+	virtual void setGradientMask(VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew) = 0;
+	virtual void setPatternMask(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY) = 0;
+
+	virtual void set4ColorGeometry(FPoint p1, FPoint p2, FPoint p3, FPoint p4, FPoint c1, FPoint c2, FPoint c3, FPoint c4) = 0;
+	virtual void set4ColorColors(const ScColorShade& col1, const ScColorShade& col2, const ScColorShade& col3, const ScColorShade& col4) = 0;
+	virtual void setDiamondGeometry(FPoint p1, FPoint p2, FPoint p3, FPoint p4, FPoint c1, FPoint c2, FPoint c3, FPoint c4, FPoint c5) = 0;
+	virtual void setMeshGradient(FPoint p1, FPoint p2, FPoint p3, FPoint p4, QList<QList<meshPoint> > meshArray) = 0;
+	virtual void setMeshGradient(FPoint p1, FPoint p2, FPoint p3, FPoint p4, QList<meshGradientPatch> meshPatches) = 0;
+
 	virtual void setClipPath() = 0;
 
 	virtual void drawImage( ScImage *image, ScPainterExBase::ImageMode mode ) = 0;
@@ -121,11 +134,15 @@
 	virtual void restore() = 0;
 
 	virtual void setRasterOp( int op ) = 0;
+	virtual void setBlendModeFill( int blendMode ) = 0;
+	virtual void setBlendModeStroke( int blendMode ) = 0;
 
-	VGradientEx m_fillGradient;
-	VGradientEx m_strokeGradient;
-	ScPattern*  m_pattern;
-	QTransform     m_patternTransform;
+	VGradientEx  m_fillGradient;
+	VGradientEx  m_strokeGradient;
+	VGradientEx  m_maskGradient;
+	ScPattern*   m_pattern;
+	ScPattern*   m_maskPattern;
+	QTransform   m_patternTransform;
 };
 
 #endif




More information about the scribus-commit mailing list