1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 
8 #include "slaoutput.h"
9 
10 #include <poppler/GlobalParams.h>
11 #include <poppler/poppler-config.h>
12 #include <poppler/FileSpec.h>
13 #include <poppler/fofi/FoFiTrueType.h>
14 #include <QApplication>
15 #include <QFile>
16 #include "commonstrings.h"
17 #include "loadsaveplugin.h"
18 #include "sccolorengine.h"
19 #include "util.h"
20 #include "util_math.h"
21 #include <tiffio.h>
22 
23 //#ifndef DEBUG_TEXT_IMPORT
24 //	#define DEBUG_TEXT_IMPORT
25 //#endif
26 
27 namespace
28 {
29 	// Compute the intersection of two paths while considering the fillrule of each of them.
30 	// QPainterPath has the right interface to do the operation but is currently buggy.
31 	// See for example https://bugreports.qt.io/browse/QTBUG-83102. Thus this function
32 	// applies some heuristics to find the best result. As soon QPainterPath is fixed
33 	// one can just use a.intersected(b) wherever this function is called.
34 	// TODO: Find an alternative to QPainterPath that works for different fill rules.
intersection(QPainterPath const & a,QPainterPath const & b)35 	QPainterPath intersection(QPainterPath const &a, QPainterPath const &b)
36 	{
37 		// An empty path is treated like the whole area.
38 		if (a.elementCount() == 0)
39 			return b;
40 		if (b.elementCount() == 0)
41 			return a;
42 
43 		QPainterPath ret_a = a.intersected(b);
44 		QPainterPath ret_b = b.intersected(a);
45 		// Sometimes the resulting paths are not closed even though they should.
46 		// Close them now.
47 		ret_a.closeSubpath();
48 		ret_b.closeSubpath();
49 
50 		// Most of the time one of the two operations returns an empty path while the other
51 		// gives us the desired result. Return the non-empty one.
52 		if (ret_a.elementCount() == 0)
53 			return ret_b;
54 		if (ret_b.elementCount() == 0)
55 			return ret_a;
56 
57 		// There are cases where both intersections are not empty but one of them is quite
58 		// complicated with several subpaths, etc. We return the simpler one.
59 		return (ret_a.elementCount() <= ret_b.elementCount()) ? ret_a : ret_b;
60 	}
61 
62 	// Invert preblending matte values into the color values. Assuming that c and alpha are RGBA components
63 	// between 0 and 255.
unblendMatte(int c,int alpha,int matte)64 	int unblendMatte(int c, int alpha, int matte)
65 	{
66 		if (alpha == 0)
67 			return matte;
68 		int ret = matte + ((c - matte) * 255) / alpha;
69 		if (ret < 0)
70 			return 0;
71 		if (ret > 255)
72 			return 255;
73 		return ret;
74 	}
75 }
76 
LinkSubmitForm(Object * actionObj)77 LinkSubmitForm::LinkSubmitForm(Object *actionObj)
78 {
79 	if (!actionObj->isDict())
80 		return;
81 
82 	Object obj1 = actionObj->dictLookup("F");
83 	if (!obj1.isNull())
84 	{
85 		if (obj1.isDict())
86 		{
87 			Object obj3 = obj1.dictLookup("FS");
88 			if (!obj3.isNull())
89 			{
90 				if (obj3.isName())
91 				{
92 					POPPLER_CONST char *name = obj3.getName();
93 					if (!strcmp(name, "URL"))
94 					{
95 						Object obj2 = obj1.dictLookup("F");
96 						if (!obj2.isNull())
97 							fileName = obj2.getString()->copy();
98 					}
99 				}
100 			}
101 		}
102 	}
103 	obj1 = actionObj->dictLookup("Flags");
104 	if (!obj1.isNull())
105 	{
106 		if (obj1.isNum())
107 			m_flags = obj1.getInt();
108 	}
109 }
110 
~LinkSubmitForm()111 LinkSubmitForm::~LinkSubmitForm()
112 {
113 	delete fileName;
114 }
115 
LinkImportData(Object * actionObj)116 LinkImportData::LinkImportData(Object *actionObj)
117 {
118 	if (!actionObj->isDict())
119 		return;
120 	Object obj1 = actionObj->dictLookup("F");
121 	if (obj1.isNull())
122 		return;
123 
124 	Object obj3 = getFileSpecNameForPlatform(&obj1);
125 	if (!obj3.isNull())
126 		fileName = obj3.getString()->copy();
127 }
128 
~LinkImportData()129 LinkImportData::~LinkImportData()
130 {
131 	delete fileName;
132 }
133 
~AnoOutputDev()134 AnoOutputDev::~AnoOutputDev()
135 {
136 	delete fontName;
137 	delete itemText;
138 }
139 
AnoOutputDev(ScribusDoc * doc,QStringList * importedColors)140 AnoOutputDev::AnoOutputDev(ScribusDoc* doc, QStringList *importedColors)
141 {
142 	m_doc = doc;
143 	m_importedColors = importedColors;
144 	currColorText = "Black";
145 	currColorFill = CommonStrings::None;
146 	currColorStroke = CommonStrings::None;
147 }
148 
eoFill(GfxState * state)149 void AnoOutputDev::eoFill(GfxState *state)
150 {
151 	int shade = 100;
152 	currColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade);
153 }
154 
fill(GfxState * state)155 void AnoOutputDev::fill(GfxState *state)
156 {
157 	int shade = 100;
158 	currColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade);
159 }
160 
stroke(GfxState * state)161 void AnoOutputDev::stroke(GfxState *state)
162 {
163 	int shade = 100;
164 	currColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &shade);
165 }
166 
drawString(GfxState * state,POPPLER_CONST GooString * s)167 void AnoOutputDev::drawString(GfxState *state, POPPLER_CONST GooString *s)
168 {
169 	int shade = 100;
170 	currColorText = getColor(state->getFillColorSpace(), state->getFillColor(), &shade);
171 	fontSize = state->getFontSize();
172 	if (state->getFont())
173 		fontName = state->getFont()->getName()->copy();
174 	itemText = s->copy();
175 }
176 
getColor(GfxColorSpace * color_space,POPPLER_CONST_070 GfxColor * color,int * shade)177 QString AnoOutputDev::getColor(GfxColorSpace *color_space, POPPLER_CONST_070 GfxColor *color, int *shade)
178 {
179 	QString fNam;
180 	QString namPrefix = "FromPDF";
181 	ScColor tmp;
182 	tmp.setSpotColor(false);
183 	tmp.setRegistrationColor(false);
184 	*shade = 100;
185 	if ((color_space->getMode() == csDeviceRGB) || (color_space->getMode() == csCalRGB))
186 	{
187 		GfxRGB rgb;
188 		color_space->getRGB(color, &rgb);
189 		double Rc = colToDbl(rgb.r);
190 		double Gc = colToDbl(rgb.g);
191 		double Bc = colToDbl(rgb.b);
192 		tmp.setRgbColorF(Rc, Gc, Bc);
193 		fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
194 	}
195 	else if (color_space->getMode() == csDeviceCMYK)
196 	{
197 		GfxCMYK cmyk;
198 		color_space->getCMYK(color, &cmyk);
199 		double Cc = colToDbl(cmyk.c);
200 		double Mc = colToDbl(cmyk.m);
201 		double Yc = colToDbl(cmyk.y);
202 		double Kc = colToDbl(cmyk.k);
203 		tmp.setCmykColorF(Cc, Mc, Yc, Kc);
204 		fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
205 	}
206 	else if ((color_space->getMode() == csCalGray) || (color_space->getMode() == csDeviceGray))
207 	{
208 		GfxGray gray;
209 		color_space->getGray(color, &gray);
210 		double Kc = 1.0 - colToDbl(gray);
211 		tmp.setCmykColorF(0, 0, 0, Kc);
212 		fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
213 	}
214 	else if (color_space->getMode() == csSeparation)
215 	{
216 		GfxSeparationColorSpace* sepColorSpace = (GfxSeparationColorSpace*)color_space;
217 		GfxColorSpace* altColorSpace = sepColorSpace->getAlt();
218 		QString name = QString(sepColorSpace->getName()->getCString());
219 		bool isRegistrationColor = (name == "All");
220 		if (isRegistrationColor)
221 		{
222 			tmp.setCmykColorF(1.0, 1.0, 1.0, 1.0);
223 			tmp.setRegistrationColor(true);
224 			name = "Registration";
225 		}
226 		else if ((altColorSpace->getMode() == csDeviceRGB) || (altColorSpace->getMode() == csCalRGB))
227 		{
228 			double x = 1.0;
229 			double comps[gfxColorMaxComps];
230 			sepColorSpace->getFunc()->transform(&x, comps);
231 			tmp.setRgbColorF(comps[0], comps[1], comps[2]);
232 		}
233 		else if ((altColorSpace->getMode() == csCalGray) || (altColorSpace->getMode() == csDeviceGray))
234 		{
235 			double x = 1.0;
236 			double comps[gfxColorMaxComps];
237 			sepColorSpace->getFunc()->transform(&x, comps);
238 			tmp.setCmykColorF(0.0, 0.0, 0.0, 1.0 - comps[0]);
239 		}
240 		else if (altColorSpace->getMode() == csLab)
241 		{
242 			double x = 1.0;
243 			double comps[gfxColorMaxComps];
244 			sepColorSpace->getFunc()->transform(&x, comps);
245 			tmp.setLabColor(comps[0], comps[1], comps[2]);
246 		}
247 		else
248 		{
249 			GfxCMYK cmyk;
250 			color_space->getCMYK(color, &cmyk);
251 			double Cc = colToDbl(cmyk.c);
252 			double Mc = colToDbl(cmyk.m);
253 			double Yc = colToDbl(cmyk.y);
254 			double Kc = colToDbl(cmyk.k);
255 			tmp.setCmykColorF(Cc, Mc, Yc, Kc);
256 		}
257 		tmp.setSpotColor(true);
258 
259 		fNam = m_doc->PageColors.tryAddColor(name, tmp);
260 		*shade = qRound(colToDbl(color->c[0]) * 100);
261 	}
262 	else
263 	{
264 		GfxRGB rgb;
265 		color_space->getRGB(color, &rgb);
266 		double Rc = colToDbl(rgb.r);
267 		double Gc = colToDbl(rgb.g);
268 		double Bc = colToDbl(rgb.b);
269 		tmp.setRgbColorF(Rc, Gc, Bc);
270 		fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
271 	//	qDebug() << "update fill color other colorspace" << color_space->getMode() << "treating as rgb" << Rc << Gc << Bc;
272 	}
273 	if (fNam == namPrefix+tmp.name())
274 		m_importedColors->append(fNam);
275 	return fNam;
276 }
277 
SlaOutputDev(ScribusDoc * doc,QList<PageItem * > * Elements,QStringList * importedColors,int flags)278 SlaOutputDev::SlaOutputDev(ScribusDoc* doc, QList<PageItem*> *Elements, QStringList *importedColors, int flags)
279 {
280 	m_doc = doc;
281 	m_Elements = Elements;
282 	pushGroup();
283 	m_importedColors = importedColors;
284 	m_currColorStroke = "Black";
285 	m_currColorFill = "Black";
286 	tmpSel = new Selection(m_doc, false);
287 	importerFlags = flags;
288 	currentLayer = m_doc->activeLayer();
289 	layersSetByOCG = false;
290 }
291 
~SlaOutputDev()292 SlaOutputDev::~SlaOutputDev()
293 {
294 	m_groupStack.clear();
295 	tmpSel->clear();
296 	delete tmpSel;
297 	delete m_fontEngine;
298 }
299 
300 /* get Actions not implemented by Poppler */
SC_getAction(AnnotWidget * ano)301 LinkAction* SlaOutputDev::SC_getAction(AnnotWidget *ano)
302 {
303 	LinkAction *linkAction = nullptr;
304 	Object obj;
305 	Ref refa = ano->getRef();
306 
307 	obj = xref->fetch(refa.num, refa.gen);
308 	if (obj.isDict())
309 	{
310 		Dict* adic = obj.getDict();
311 		POPPLER_CONST_075 Object POPPLER_REF additionalActions = adic->lookupNF("A");
312 		Object additionalActionsObject = additionalActions.fetch(pdfDoc->getXRef());
313 		if (additionalActionsObject.isDict())
314 		{
315 			Object actionObject = additionalActionsObject.dictLookup("S");
316 			if (actionObject.isName("ImportData"))
317 			{
318 				linkAction = new LinkImportData(&additionalActionsObject);
319 			}
320 			else if (actionObject.isName("SubmitForm"))
321 			{
322 				linkAction = new LinkSubmitForm(&additionalActionsObject);
323 			}
324 		}
325 	}
326 	return linkAction;
327 }
328 
329 /* Replacement for the crippled Poppler function LinkAction* AnnotWidget::getAdditionalAction(AdditionalActionsType type) */
330 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
SC_getAdditionalAction(const char * key,AnnotWidget * ano)331 std::unique_ptr<LinkAction> SlaOutputDev::SC_getAdditionalAction(const char *key, AnnotWidget *ano)
332 {
333 	std::unique_ptr<LinkAction> linkAction;
334 #else
335 LinkAction* SlaOutputDev::SC_getAdditionalAction(const char *key, AnnotWidget *ano)
336 {
337 	LinkAction *linkAction = nullptr;
338 #endif
339 	Object obj;
340 	Ref refa = ano->getRef();
341 
342 	obj = xref->fetch(refa.num, refa.gen);
343 	if (obj.isDict())
344 	{
345 		Dict* adic = obj.getDict();
346 		POPPLER_CONST_075 Object POPPLER_REF additionalActions = adic->lookupNF("AA");
347 		Object additionalActionsObject = additionalActions.fetch(pdfDoc->getXRef());
348 		if (additionalActionsObject.isDict())
349 		{
350 			Object actionObject = additionalActionsObject.dictLookup(key);
351 			if (actionObject.isDict())
352 				linkAction = LinkAction::parseAction(&actionObject, pdfDoc->getCatalog()->getBaseURI());
353 		}
354 	}
355 	return linkAction;
356 }
357 
358 GBool SlaOutputDev::annotations_callback(Annot *annota, void *user_data)
359 {
360 	SlaOutputDev *dev = (SlaOutputDev*)user_data;
361 	PDFRectangle *box = annota->getRect();
362 	double xCoor = dev->m_doc->currentPage()->xOffset() + box->x1 - dev->cropOffsetX;
363 	double yCoor = dev->m_doc->currentPage()->yOffset() + dev->m_doc->currentPage()->height() - box->y2 + dev->cropOffsetY;
364 	double width = box->x2 - box->x1;
365 	double height = box->y2 - box->y1;
366 	if (dev->rotate == 90)
367 	{
368 		xCoor = dev->m_doc->currentPage()->xOffset() - dev->cropOffsetX + box->y2;
369 		yCoor = dev->m_doc->currentPage()->yOffset() + dev->cropOffsetY + box->x1;
370 	}
371 	else if (dev->rotate == 180)
372 	{
373 		xCoor = dev->m_doc->currentPage()->xOffset() - dev->cropOffsetX + dev->m_doc->currentPage()->width() - box->x1;
374 		yCoor = dev->m_doc->currentPage()->yOffset() + dev->cropOffsetY + box->y2;
375 	}
376 	else if (dev->rotate == 270)
377 	{
378 		xCoor = dev->m_doc->currentPage()->xOffset() - dev->cropOffsetX + dev->m_doc->currentPage()->width() - box->y2;
379 		yCoor = dev->m_doc->currentPage()->yOffset() + dev->cropOffsetY + dev->m_doc->currentPage()->height() - box->x1;
380 	}
381 	bool retVal = true;
382 	if (annota->getType() == Annot::typeText)
383 		retVal = !dev->handleTextAnnot(annota, xCoor, yCoor, width, height);
384 	else if (annota->getType() == Annot::typeLink)
385 		retVal = !dev->handleLinkAnnot(annota, xCoor, yCoor, width, height);
386 	else if (annota->getType() == Annot::typeWidget)
387 		retVal = !dev->handleWidgetAnnot(annota, xCoor, yCoor, width, height);
388 	return retVal;
389 }
390 
391 bool SlaOutputDev::handleTextAnnot(Annot* annota, double xCoor, double yCoor, double width, double height)
392 {
393 	AnnotText *anl = (AnnotText*)annota;
394 	int z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, CommonStrings::None, CommonStrings::None);
395 	PageItem *ite = m_doc->Items->at(z);
396 	int flg = annota->getFlags();
397 	if (!(flg & 16))
398 		ite->setRotation(rotate, true);
399 	ite->ClipEdited = true;
400 	ite->FrameType = 3;
401 	ite->setFillEvenOdd(false);
402 	ite->Clip = flattenPath(ite->PoLine, ite->Segments);
403 	ite->ContourLine = ite->PoLine.copy();
404 	ite->setTextFlowMode(PageItem::TextFlowDisabled);
405 	m_Elements->append(ite);
406 	if (m_groupStack.count() != 0)
407 	{
408 		m_groupStack.top().Items.append(ite);
409 		applyMask(ite);
410 	}
411 	ite->setIsAnnotation(true);
412 	ite->AutoName = false;
413 	ite->annotation().setType(Annotation::Text);
414 	ite->annotation().setActionType(Annotation::Action_None);
415 	ite->annotation().setAnOpen(anl->getOpen());
416 	QString iconName = UnicodeParsedString(anl->getIcon());
417 	if (iconName == "Note")
418 		ite->annotation().setIcon(Annotation::Icon_Note);
419 	else if (iconName == "Comment")
420 		ite->annotation().setIcon(Annotation::Icon_Comment);
421 	else if (iconName == "Key")
422 		ite->annotation().setIcon(Annotation::Icon_Key);
423 	else if (iconName == "Help")
424 		ite->annotation().setIcon(Annotation::Icon_Help);
425 	else if (iconName == "NewParagraph")
426 		ite->annotation().setIcon(Annotation::Icon_NewParagraph);
427 	else if (iconName == "Paragraph")
428 		ite->annotation().setIcon(Annotation::Icon_Paragraph);
429 	else if (iconName == "Insert")
430 		ite->annotation().setIcon(Annotation::Icon_Insert);
431 	else if (iconName == "Cross")
432 		ite->annotation().setIcon(Annotation::Icon_Cross);
433 	else if (iconName == "Circle")
434 		ite->annotation().setIcon(Annotation::Icon_Circle);
435 	else
436 		ite->annotation().setIcon(Annotation::Icon_Note);
437 	ite->setItemName( CommonStrings::itemName_TextAnnotation + QString("%1").arg(m_doc->TotalItems));
438 	ite->itemText.insertChars(UnicodeParsedString(annota->getContents()));
439 	ite->itemText.trim();
440 	return true;
441 }
442 
443 bool SlaOutputDev::handleLinkAnnot(Annot* annota, double xCoor, double yCoor, double width, double height)
444 {
445 	AnnotLink *anl = (AnnotLink*)annota;
446 	LinkAction *act = anl->getAction();
447 	if (!act)
448 		return false;
449 	bool validLink = false;
450 	int pagNum = 0;
451 	int xco = 0;
452 	int yco = 0;
453 	QString fileName = "";
454 	if (act->getKind() == actionGoTo)
455 	{
456 		LinkGoTo *gto = (LinkGoTo*) act;
457 		POPPLER_CONST LinkDest *dst = gto->getDest();
458 		if (dst)
459 		{
460 			if (dst->getKind() == destXYZ)
461 			{
462 				if (dst->isPageRef())
463 				{
464 					Ref dstr = dst->getPageRef();
465 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 76, 0)
466 					pagNum = pdfDoc->findPage(dstr);
467 #else
468 					pagNum = pdfDoc->findPage(dstr.num, dstr.gen);
469 #endif
470 				}
471 				else
472 					pagNum = dst->getPageNum();
473 				xco = dst->getLeft();
474 				yco = dst->getTop();
475 				validLink = true;
476 			}
477 		}
478 		else
479 		{
480 			POPPLER_CONST GooString *ndst = gto->getNamedDest();
481 			if (ndst)
482 			{
483 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
484 				std::unique_ptr<LinkDest> dstn = pdfDoc->findDest(ndst);
485 #else
486 				LinkDest *dstn = pdfDoc->findDest(ndst);
487 #endif
488 				if (dstn)
489 				{
490 					if (dstn->getKind() == destXYZ)
491 					{
492 						if (dstn->isPageRef())
493 						{
494 							Ref dstr = dstn->getPageRef();
495 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 76, 0)
496 							pagNum = pdfDoc->findPage(dstr);
497 #else
498 							pagNum = pdfDoc->findPage(dstr.num, dstr.gen);
499 #endif
500 						}
501 						else
502 							pagNum = dstn->getPageNum();
503 						xco = dstn->getLeft();
504 						yco = dstn->getTop();
505 						validLink = true;
506 					}
507 				}
508 			}
509 		}
510 	}
511 	else if (act->getKind() == actionGoToR)
512 	{
513 		LinkGoToR *gto = (LinkGoToR*)act;
514 		fileName = UnicodeParsedString(gto->getFileName());
515 		POPPLER_CONST LinkDest *dst = gto->getDest();
516 		if (dst)
517 		{
518 			if (dst->getKind() == destXYZ)
519 			{
520 				pagNum = dst->getPageNum();
521 				xco = dst->getLeft();
522 				yco = dst->getTop();
523 				validLink = true;
524 			}
525 		}
526 		else
527 		{
528 			POPPLER_CONST GooString *ndst = gto->getNamedDest();
529 			if (ndst)
530 			{
531 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
532 				std::unique_ptr<LinkDest> dstn = pdfDoc->findDest(ndst);
533 #else
534 				LinkDest *dstn = pdfDoc->findDest(ndst);
535 #endif
536 				if (dstn)
537 				{
538 					if (dstn->getKind() == destXYZ)
539 					{
540 						pagNum = dstn->getPageNum();
541 						xco = dstn->getLeft();
542 						yco = dstn->getTop();
543 						validLink = true;
544 					}
545 				}
546 			}
547 		}
548 	}
549 	else if (act->getKind() == actionURI)
550 	{
551 		LinkURI *gto = (LinkURI*)act;
552 		validLink = true;
553 		fileName = UnicodeParsedString(gto->getURI());
554 	}
555 	if (validLink)
556 	{
557 		int z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, CommonStrings::None, CommonStrings::None);
558 		PageItem *ite = m_doc->Items->at(z);
559 		int flg = annota->getFlags();
560 		if (!(flg & 16))
561 			ite->setRotation(rotate, true);
562 		ite->ClipEdited = true;
563 		ite->FrameType = 3;
564 		ite->setFillEvenOdd(false);
565 		ite->Clip = flattenPath(ite->PoLine, ite->Segments);
566 		ite->ContourLine = ite->PoLine.copy();
567 		ite->setTextFlowMode(PageItem::TextFlowDisabled);
568 		m_Elements->append(ite);
569 		if (m_groupStack.count() != 0)
570 		{
571 			m_groupStack.top().Items.append(ite);
572 			applyMask(ite);
573 		}
574 		ite->setIsAnnotation(true);
575 		ite->AutoName = false;
576 		if (act->getKind() == actionGoTo)
577 		{
578 			ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1));
579 			ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco));
580 			ite->annotation().setActionType(2);
581 		}
582 		else if (act->getKind() == actionGoToR)
583 		{
584 			ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1));
585 			ite->annotation().setExtern(fileName);
586 			ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco));
587 			ite->annotation().setActionType(9);
588 		}
589 		else if (act->getKind() == actionURI)
590 		{
591 			ite->annotation().setAction("");
592 			ite->annotation().setExtern(fileName);
593 			ite->annotation().setActionType(8);
594 		}
595 		ite->annotation().setType(Annotation::Link);
596 		ite->setItemName( CommonStrings::itemName_LinkAnnotation + QString("%1").arg(m_doc->TotalItems));
597 	}
598 	return validLink;
599 }
600 
601 bool SlaOutputDev::handleWidgetAnnot(Annot* annota, double xCoor, double yCoor, double width, double height)
602 {
603 	bool retVal = false;
604 	bool found = false;
605 
606 	if (!m_formWidgets)
607 		return false;
608 
609 	int formcount = m_formWidgets->getNumWidgets();
610 	for (int i = 0; i < formcount; ++i)
611 	{
612 		FormWidget *fm = m_formWidgets->getWidget(i);
613 		if (!fm)
614 			continue;
615 		AnnotWidget *ano = fm->getWidgetAnnotation();
616 		if (!ano)
617 			continue;
618 		if (ano != (AnnotWidget*) annota)
619 			continue;
620 		found = true;
621 		int wtyp = -1;
622 		if (fm->getType() == formButton)
623 		{
624 			FormWidgetButton *btn = (FormWidgetButton*)fm;
625 			if (btn)
626 			{
627 				if (btn->getButtonType() == formButtonCheck)
628 				{
629 					wtyp = Annotation::Checkbox;
630 					retVal = true;
631 				}
632 				else if (btn->getButtonType() == formButtonPush)
633 				{
634 					wtyp = Annotation::Button;
635 					retVal = true;
636 				}
637 				else if (btn->getButtonType() == formButtonRadio)
638 				{
639 					wtyp = Annotation::RadioButton;
640 					retVal = true;
641 				}
642 			}
643 		}
644 		else if (fm->getType() == formText)
645 		{
646 			wtyp = Annotation::Textfield;
647 			retVal = true;
648 		}
649 		else if (fm->getType() == formChoice)
650 		{
651 			FormWidgetChoice *btn = (FormWidgetChoice*)fm;
652 			if (btn)
653 			{
654 				if (btn->isCombo())
655 				{
656 					wtyp = Annotation::Combobox;
657 					retVal = true;
658 				}
659 				else if (btn->isListBox())
660 				{
661 					wtyp = Annotation::Listbox;
662 					retVal = true;
663 				}
664 			}
665 		}
666 		if (retVal)
667 		{
668 			AnnotAppearanceCharacs *achar = ano->getAppearCharacs();
669 			bool fgFound = false;
670 			bool bgFound = false;
671 			if (achar)
672 			{
673 				POPPLER_CONST AnnotColor *bgCol = achar->getBackColor();
674 				if (bgCol)
675 				{
676 					bgFound = true;
677 					m_currColorFill = getAnnotationColor(bgCol);
678 				}
679 				else
680 					m_currColorFill = CommonStrings::None;
681 				POPPLER_CONST AnnotColor *fgCol = achar->getBorderColor();
682 				if (fgCol)
683 				{
684 					fgFound = true;
685 					m_currColorStroke = getAnnotationColor(fgCol);
686 				}
687 				else
688 				{
689 					fgCol = achar->getBackColor();
690 					if (fgCol)
691 						m_currColorStroke = getAnnotationColor(fgCol);
692 					else
693 						m_currColorStroke = CommonStrings::None;
694 				}
695 			}
696 			QString m_currColorText = "Black";
697 			double fontSize = 12;
698 			QString fontName = "";
699 			QString itemText = "";
700 			AnnotAppearance *apa = annota->getAppearStreams();
701 			if (apa || !achar)
702 			{
703 				AnoOutputDev *annotOutDev = new AnoOutputDev(m_doc, m_importedColors);
704 				Gfx *gfx = new Gfx(pdfDoc, annotOutDev, pdfDoc->getPage(m_actPage)->getResourceDict(), annota->getRect(), nullptr);
705 				ano->draw(gfx, false);
706 				if (!bgFound)
707 					m_currColorFill = annotOutDev->currColorFill;
708 				if (!fgFound)
709 					m_currColorStroke = annotOutDev->currColorStroke;
710 				m_currColorText = annotOutDev->currColorText;
711 				fontSize = annotOutDev->fontSize;
712 				fontName = UnicodeParsedString(annotOutDev->fontName);
713 				itemText = UnicodeParsedString(annotOutDev->itemText);
714 				delete gfx;
715 				delete annotOutDev;
716 			}
717 			int z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, m_currColorFill, CommonStrings::None);
718 			PageItem *ite = m_doc->Items->at(z);
719 			int flg = annota->getFlags();
720 			if (!(flg & 16))
721 				ite->setRotation(rotate, true);
722 			ite->ClipEdited = true;
723 			ite->FrameType = 3;
724 			ite->setFillEvenOdd(false);
725 			ite->Clip = flattenPath(ite->PoLine, ite->Segments);
726 			ite->ContourLine = ite->PoLine.copy();
727 			ite->setTextFlowMode(PageItem::TextFlowDisabled);
728 			m_Elements->append(ite);
729 			if (m_groupStack.count() != 0)
730 			{
731 				m_groupStack.top().Items.append(ite);
732 				applyMask(ite);
733 			}
734 			ite->setIsAnnotation(true);
735 			ite->AutoName = false;
736 			AnnotBorder *brd = annota->getBorder();
737 			if (brd)
738 			{
739 				int bsty = brd->getStyle();
740 				if (bsty == AnnotBorder::borderDashed)
741 					bsty = 1;
742 				else if (bsty == AnnotBorder::borderBeveled)
743 					bsty = 3;
744 				else if (bsty == AnnotBorder::borderInset)
745 					bsty = 4;
746 				else if (bsty == AnnotBorder::borderUnderlined)
747 					bsty = 2;
748 				ite->annotation().setBorderStyle(bsty);
749 				ite->annotation().setBorderColor(m_currColorStroke);
750 				ite->annotation().setBorderWidth(qRound(brd->getWidth()));
751 			}
752 			else
753 			{
754 				ite->annotation().setBorderStyle(0);
755 				ite->annotation().setBorderColor(CommonStrings::None);
756 				ite->annotation().setBorderWidth(0);
757 			}
758 			QString tmTxt = "";
759 			tmTxt = UnicodeParsedString(fm->getPartialName());
760 			if (!tmTxt.isEmpty())
761 				ite->setItemName(tmTxt);
762 			tmTxt = "";
763 			tmTxt = UnicodeParsedString(fm->getAlternateUiName());
764 			if (!tmTxt.isEmpty())
765 				ite->annotation().setToolTip(tmTxt);
766 			tmTxt = "";
767 			if (achar)
768 			{
769 				tmTxt = UnicodeParsedString(achar->getRolloverCaption());
770 				if (!tmTxt.isEmpty())
771 					ite->annotation().setRollOver(tmTxt);
772 				tmTxt = "";
773 				tmTxt = UnicodeParsedString(achar->getAlternateCaption());
774 				if (!tmTxt.isEmpty())
775 					ite->annotation().setDown(tmTxt);
776 			}
777 			ite->annotation().setType(wtyp);
778 			ite->annotation().setFlag(0);
779 			if (flg & 2)
780 				ite->annotation().setVis(1);
781 			if (flg & 32)
782 				ite->annotation().setVis(3);
783 			if (wtyp == Annotation::Button)
784 			{
785 				ite->setFillColor(m_currColorFill);
786 				if (achar)
787 					ite->itemText.insertChars(UnicodeParsedString(achar->getNormalCaption()));
788 				else
789 					ite->itemText.insertChars(itemText);
790 				applyTextStyle(ite, fontName, m_currColorText, fontSize);
791 				ite->annotation().addToFlag(Annotation::Flag_PushButton);
792 				FormWidgetButton *btn = (FormWidgetButton*)fm;
793 				if (!btn->isReadOnly())
794 					ite->annotation().addToFlag(Annotation::Flag_Edit);
795 				handleActions(ite, ano);
796 			}
797 			else if (wtyp == Annotation::Textfield)
798 			{
799 				FormWidgetText *btn = (FormWidgetText*)fm;
800 				if (btn)
801 				{
802 					ite->itemText.insertChars(UnicodeParsedString(btn->getContent()));
803 					applyTextStyle(ite, fontName, m_currColorText, fontSize);
804 					ite->itemText.trim();
805 					if (btn->isMultiline())
806 						ite->annotation().addToFlag(Annotation::Flag_Multiline);
807 					if (btn->isPassword())
808 						ite->annotation().addToFlag(Annotation::Flag_Password);
809 					if (btn->noSpellCheck())
810 						ite->annotation().addToFlag(Annotation::Flag_DoNotSpellCheck);
811 					if (btn->noScroll())
812 						ite->annotation().addToFlag(Annotation::Flag_DoNotScroll);
813 					int mxLen = btn->getMaxLen();
814 					if (mxLen > 0)
815 						ite->annotation().setMaxChar(mxLen);
816 					else
817 						ite->annotation().setMaxChar(-1);
818 					if (!btn->isReadOnly())
819 						ite->annotation().addToFlag(Annotation::Flag_Edit);
820 					handleActions(ite, ano);
821 				}
822 			}
823 			else if (wtyp == Annotation::Checkbox)
824 			{
825 				FormWidgetButton *btn = (FormWidgetButton*)fm;
826 				if (btn)
827 				{
828 					ite->annotation().setIsChk(btn->getState());
829 					ite->annotation().setCheckState(ite->annotation().IsChk());
830 					handleActions(ite, ano);
831 					if (itemText == "4")
832 						ite->annotation().setChkStil(0);
833 					else if (itemText == "5")
834 						ite->annotation().setChkStil(1);
835 					else if (itemText == "F")
836 						ite->annotation().setChkStil(2);
837 					else if (itemText == "l")
838 						ite->annotation().setChkStil(3);
839 					else if (itemText == "H")
840 						ite->annotation().setChkStil(4);
841 					else if (itemText == "n")
842 						ite->annotation().setChkStil(5);
843 					else
844 						ite->annotation().setChkStil(0);
845 					if (!btn->isReadOnly())
846 						ite->annotation().addToFlag(Annotation::Flag_Edit);
847 				}
848 			}
849 			else if ((wtyp == Annotation::Combobox) || (wtyp == Annotation::Listbox))
850 			{
851 				FormWidgetChoice *btn = (FormWidgetChoice*)fm;
852 				if (btn)
853 				{
854 					if (wtyp == 5)
855 						ite->annotation().addToFlag(Annotation::Flag_Combo);
856 					int co = btn->getNumChoices();
857 					if (co > 0)
858 					{
859 						QString inh = UnicodeParsedString(btn->getChoice(0));
860 						for (int a = 1; a < co; a++)
861 						{
862 							inh += "\n" + UnicodeParsedString(btn->getChoice(a));
863 						}
864 						ite->itemText.insertChars(inh);
865 					}
866 					applyTextStyle(ite, fontName, m_currColorText, fontSize);
867 					if (!btn->isReadOnly())
868 						ite->annotation().addToFlag(Annotation::Flag_Edit);
869 					handleActions(ite, ano);
870 				}
871 			}
872 			else if (wtyp == Annotation::RadioButton)
873 			{
874 				FormWidgetButton *btn = (FormWidgetButton*)fm;
875 				if (btn)
876 				{
877 					ite->setItemName( CommonStrings::itemName_RadioButton + QString("%1").arg(m_doc->TotalItems));
878 					ite->annotation().setIsChk(btn->getState());
879 					ite->annotation().setCheckState(ite->annotation().IsChk());
880 					handleActions(ite, ano);
881 					m_radioButtons.insert(annota->getRef().num, ite);
882 				}
883 			}
884 		}
885 		break;
886 	}
887 	if (!found)
888 	{
889 		Object obj1;
890 		Ref refa = annota->getRef();
891 		obj1 = xref->fetch(refa.num, refa.gen);
892 		if (obj1.isDict())
893 		{
894 			Dict* dict = obj1.getDict();
895 			Object obj2 = dict->lookup("Kids");
896 			//childs
897 			if (obj2.isArray())
898 			{
899 				// Load children
900 				QList<int> radList;
901 				for (int i = 0; i < obj2.arrayGetLength(); i++)
902 				{
903 					POPPLER_CONST_075 Object POPPLER_REF childRef = obj2.arrayGetNF(i);
904 					if (!childRef.isRef())
905 						continue;
906 					Object childObj = obj2.arrayGet(i);
907 					if (!childObj.isDict())
908 						continue;
909 					const Ref ref = childRef.getRef();
910 					radList.append(ref.num);
911 				}
912 				QString tmTxt = UnicodeParsedString(annota->getName());
913 				m_radioMap.insert(tmTxt, radList);
914 			}
915 		}
916 	}
917 	return retVal;
918 }
919 
920 void SlaOutputDev::applyTextStyle(PageItem* ite, const QString& fontName, const QString& textColor, double fontSize)
921 {
922 	CharStyle newStyle;
923 	newStyle.setFillColor(textColor);
924 	newStyle.setFontSize(fontSize * 10);
925 	if (!fontName.isEmpty())
926 	{
927 		SCFontsIterator it(*m_doc->AllFonts);
928 		for ( ; it.hasNext() ; it.next())
929 		{
930 			ScFace& face(it.current());
931 			if ((face.psName() == fontName) && (face.usable()) && (face.type() == ScFace::TTF))
932 			{
933 				newStyle.setFont(face);
934 				break;
935 			}
936 			if ((face.family() == fontName) && (face.usable()) && (face.type() == ScFace::TTF))
937 			{
938 				newStyle.setFont(face);
939 				break;
940 			}
941 			if ((face.scName() == fontName) && (face.usable()) && (face.type() == ScFace::TTF))
942 			{
943 				newStyle.setFont(face);
944 				break;
945 			}
946 		}
947 	}
948 	ParagraphStyle dstyle(ite->itemText.defaultStyle());
949 	dstyle.charStyle().applyCharStyle(newStyle);
950 	ite->itemText.setDefaultStyle(dstyle);
951 	ite->itemText.applyCharStyle(0, ite->itemText.length(), newStyle);
952 	ite->invalid = true;
953 }
954 
955 void SlaOutputDev::handleActions(PageItem* ite, AnnotWidget *ano)
956 {
957 	LinkAction *Lact = ano->getAction();
958 	if (Lact)
959 	{
960 		if (Lact->getKind() == actionJavaScript)
961 		{
962 			LinkJavaScript *jsa = (LinkJavaScript*)Lact;
963 			if (jsa->isOk())
964 			{
965 				ite->annotation().setActionType(1);
966 				ite->annotation().setAction(UnicodeParsedString(jsa->getScript()));
967 			}
968 		}
969 		else if (Lact->getKind() == actionGoTo)
970 		{
971 			int pagNum = 0;
972 			int xco = 0;
973 			int yco = 0;
974 			LinkGoTo *gto = (LinkGoTo*)Lact;
975 			POPPLER_CONST LinkDest *dst = gto->getDest();
976 			if (dst)
977 			{
978 				if (dst->getKind() == destXYZ)
979 				{
980 					if (dst->isPageRef())
981 					{
982 						Ref dstr = dst->getPageRef();
983 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 76, 0)
984 						pagNum = pdfDoc->findPage(dstr);
985 #else
986 						pagNum = pdfDoc->findPage(dstr.num, dstr.gen);
987 #endif
988 					}
989 					else
990 						pagNum = dst->getPageNum();
991 					xco = dst->getLeft();
992 					yco = dst->getTop();
993 					ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1));
994 					ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco));
995 					ite->annotation().setActionType(2);
996 				}
997 			}
998 			else
999 			{
1000 				POPPLER_CONST GooString *ndst = gto->getNamedDest();
1001 				if (ndst)
1002 				{
1003 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1004 					std::unique_ptr<LinkDest> dstn = pdfDoc->findDest(ndst);
1005 #else
1006 					LinkDest *dstn = pdfDoc->findDest(ndst);
1007 #endif
1008 					if (dstn)
1009 					{
1010 						if (dstn->getKind() == destXYZ)
1011 						{
1012 							if (dstn->isPageRef())
1013 							{
1014 								Ref dstr = dstn->getPageRef();
1015 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 76, 0)
1016 								pagNum = pdfDoc->findPage(dstr);
1017 #else
1018 								pagNum = pdfDoc->findPage(dstr.num, dstr.gen);
1019 #endif
1020 							}
1021 							else
1022 								pagNum = dstn->getPageNum();
1023 							xco = dstn->getLeft();
1024 							yco = dstn->getTop();
1025 							ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1));
1026 							ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco));
1027 							ite->annotation().setActionType(2);
1028 						}
1029 					}
1030 				}
1031 			}
1032 		}
1033 		else if (Lact->getKind() == actionGoToR)
1034 		{
1035 			int pagNum = 0;
1036 			int xco = 0;
1037 			int yco = 0;
1038 			LinkGoToR *gto = (LinkGoToR*)Lact;
1039 			QString fileName = UnicodeParsedString(gto->getFileName());
1040 			POPPLER_CONST LinkDest *dst = gto->getDest();
1041 			if (dst)
1042 			{
1043 				if (dst->getKind() == destXYZ)
1044 				{
1045 					pagNum = dst->getPageNum();
1046 					xco = dst->getLeft();
1047 					yco = dst->getTop();
1048 					ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1));
1049 					ite->annotation().setExtern(fileName);
1050 					ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco));
1051 					ite->annotation().setActionType(9);
1052 				}
1053 			}
1054 			else
1055 			{
1056 				POPPLER_CONST GooString *ndst = gto->getNamedDest();
1057 				if (ndst)
1058 				{
1059 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1060 					std::unique_ptr<LinkDest> dstn = pdfDoc->findDest(ndst);
1061 #else
1062 					LinkDest *dstn = pdfDoc->findDest(ndst);
1063 #endif
1064 					if (dstn)
1065 					{
1066 						if (dstn->getKind() == destXYZ)
1067 						{
1068 							pagNum = dstn->getPageNum();
1069 							xco = dstn->getLeft();
1070 							yco = dstn->getTop();
1071 							ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1));
1072 							ite->annotation().setExtern(fileName);
1073 							ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco));
1074 							ite->annotation().setActionType(9);
1075 						}
1076 					}
1077 				}
1078 			}
1079 		}
1080 		else if (Lact->getKind() == actionUnknown)
1081 		{
1082 			LinkUnknown *uno = (LinkUnknown*)Lact;
1083 			QString actString = UnicodeParsedString(uno->getAction());
1084 			if (actString == "ResetForm")
1085 			{
1086 				ite->annotation().setActionType(4);
1087 			}
1088 			else
1089 			{
1090 				LinkAction* scact = SC_getAction(ano);
1091 				if (scact)
1092 				{
1093 					if (actString == "ImportData")
1094 					{
1095 						LinkImportData *impo = (LinkImportData*)scact;
1096 						if (impo->isOk())
1097 						{
1098 							ite->annotation().setActionType(5);
1099 							ite->annotation().setAction(UnicodeParsedString(impo->getFileName()));
1100 						}
1101 					}
1102 					else if (actString == "SubmitForm")
1103 					{
1104 						LinkSubmitForm *impo = (LinkSubmitForm*)scact;
1105 						if (impo->isOk())
1106 						{
1107 							ite->annotation().setActionType(3);
1108 							ite->annotation().setAction(UnicodeParsedString(impo->getFileName()));
1109 							int fl = impo->getFlags();
1110 							if (fl == 0)
1111 								ite->annotation().setHTML(0);
1112 							else if (fl == 4)
1113 								ite->annotation().setHTML(1);
1114 							else if (fl == 64)
1115 								ite->annotation().setHTML(2);
1116 							else if (fl == 512)
1117 								ite->annotation().setHTML(3);
1118 						}
1119 					}
1120 				}
1121 			}
1122 		}
1123 		else if (Lact->getKind() == actionNamed)
1124 		{
1125 			LinkNamed *uno = (LinkNamed*)Lact;
1126 			ite->annotation().setActionType(10);
1127 			ite->annotation().setAction(UnicodeParsedString(uno->getName()));
1128 		}
1129 		else
1130 			qDebug() << "Found unsupported Action of type" << Lact->getKind();
1131 	}
1132 	auto Aact = SC_getAdditionalAction("D", ano);
1133 	if (Aact)
1134 	{
1135 		if (Aact->getKind() == actionJavaScript)
1136 		{
1137 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1138 			LinkJavaScript *jsa = (LinkJavaScript*) Aact.get();
1139 #else
1140 			LinkJavaScript *jsa = (LinkJavaScript*) Aact;
1141 #endif
1142 			if (jsa->isOk())
1143 			{
1144 				ite->annotation().setD_act(UnicodeParsedString(jsa->getScript()));
1145 				ite->annotation().setAAact(true);
1146 			}
1147 		}
1148 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1149 		Aact.reset();
1150 #else
1151 		Aact = nullptr;
1152 #endif
1153 	}
1154 	Aact = SC_getAdditionalAction("E", ano);
1155 	if (Aact)
1156 	{
1157 		if (Aact->getKind() == actionJavaScript)
1158 		{
1159 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1160 			LinkJavaScript *jsa = (LinkJavaScript*) Aact.get();
1161 #else
1162 			LinkJavaScript *jsa = (LinkJavaScript*) Aact;
1163 #endif
1164 			if (jsa->isOk())
1165 			{
1166 				ite->annotation().setE_act(UnicodeParsedString(jsa->getScript()));
1167 				ite->annotation().setAAact(true);
1168 			}
1169 		}
1170 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1171 		Aact.reset();
1172 #else
1173 		Aact = nullptr;
1174 #endif
1175 	}
1176 	Aact = SC_getAdditionalAction("X", ano);
1177 	if (Aact)
1178 	{
1179 		if (Aact->getKind() == actionJavaScript)
1180 		{
1181 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1182 			LinkJavaScript *jsa = (LinkJavaScript*) Aact.get();
1183 #else
1184 			LinkJavaScript *jsa = (LinkJavaScript*) Aact;
1185 #endif
1186 			if (jsa->isOk())
1187 			{
1188 				ite->annotation().setX_act(UnicodeParsedString(jsa->getScript()));
1189 				ite->annotation().setAAact(true);
1190 			}
1191 		}
1192 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1193 		Aact.reset();
1194 #else
1195 		Aact = nullptr;
1196 #endif
1197 	}
1198 	Aact = SC_getAdditionalAction("Fo", ano);
1199 	if (Aact)
1200 	{
1201 		if (Aact->getKind() == actionJavaScript)
1202 		{
1203 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1204 			LinkJavaScript *jsa = (LinkJavaScript*) Aact.get();
1205 #else
1206 			LinkJavaScript *jsa = (LinkJavaScript*) Aact;
1207 #endif
1208 			if (jsa->isOk())
1209 			{
1210 				ite->annotation().setFo_act(UnicodeParsedString(jsa->getScript()));
1211 				ite->annotation().setAAact(true);
1212 			}
1213 		}
1214 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1215 		Aact.reset();
1216 #else
1217 		Aact = nullptr;
1218 #endif
1219 	}
1220 	Aact = SC_getAdditionalAction("Bl", ano);
1221 	if (Aact)
1222 	{
1223 		if (Aact->getKind() == actionJavaScript)
1224 		{
1225 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1226 			LinkJavaScript *jsa = (LinkJavaScript*) Aact.get();
1227 #else
1228 			LinkJavaScript *jsa = (LinkJavaScript*) Aact;
1229 #endif
1230 			if (jsa->isOk())
1231 			{
1232 				ite->annotation().setBl_act(UnicodeParsedString(jsa->getScript()));
1233 				ite->annotation().setAAact(true);
1234 			}
1235 		}
1236 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1237 		Aact.reset();
1238 #else
1239 		Aact = nullptr;
1240 #endif
1241 	}
1242 	Aact = SC_getAdditionalAction("C", ano);
1243 	if (Aact)
1244 	{
1245 		if (Aact->getKind() == actionJavaScript)
1246 		{
1247 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1248 			LinkJavaScript *jsa = (LinkJavaScript*) Aact.get();
1249 #else
1250 			LinkJavaScript *jsa = (LinkJavaScript*) Aact;
1251 #endif
1252 			if (jsa->isOk())
1253 			{
1254 				ite->annotation().setC_act(UnicodeParsedString(jsa->getScript()));
1255 				ite->annotation().setAAact(true);
1256 			}
1257 		}
1258 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1259 		Aact.reset();
1260 #else
1261 		Aact = nullptr;
1262 #endif
1263 	}
1264 	Aact = SC_getAdditionalAction("F", ano);
1265 	if (Aact)
1266 	{
1267 		if (Aact->getKind() == actionJavaScript)
1268 		{
1269 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1270 			LinkJavaScript *jsa = (LinkJavaScript*) Aact.get();
1271 #else
1272 			LinkJavaScript *jsa = (LinkJavaScript*) Aact;
1273 #endif
1274 			if (jsa->isOk())
1275 			{
1276 				ite->annotation().setF_act(UnicodeParsedString(jsa->getScript()));
1277 				ite->annotation().setAAact(true);
1278 				ite->annotation().setFormat(5);
1279 			}
1280 		}
1281 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1282 		Aact.reset();
1283 #else
1284 		Aact = nullptr;
1285 #endif
1286 	}
1287 	Aact = SC_getAdditionalAction("K", ano);
1288 	if (Aact)
1289 	{
1290 		if (Aact->getKind() == actionJavaScript)
1291 		{
1292 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1293 			LinkJavaScript *jsa = (LinkJavaScript*) Aact.get();
1294 #else
1295 			LinkJavaScript *jsa = (LinkJavaScript*) Aact;
1296 #endif
1297 			if (jsa->isOk())
1298 			{
1299 				ite->annotation().setK_act(UnicodeParsedString(jsa->getScript()));
1300 				ite->annotation().setAAact(true);
1301 				ite->annotation().setFormat(5);
1302 			}
1303 		}
1304 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1305 		Aact.reset();
1306 #else
1307 		Aact = nullptr;
1308 #endif
1309 	}
1310 	Aact = SC_getAdditionalAction("V", ano);
1311 	if (Aact)
1312 	{
1313 		if (Aact->getKind() == actionJavaScript)
1314 		{
1315 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1316 			LinkJavaScript *jsa = (LinkJavaScript*) Aact.get();
1317 #else
1318 			LinkJavaScript *jsa = (LinkJavaScript*) Aact;
1319 #endif
1320 			if (jsa->isOk())
1321 			{
1322 				ite->annotation().setV_act(UnicodeParsedString(jsa->getScript()));
1323 				ite->annotation().setAAact(true);
1324 			}
1325 		}
1326 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0)
1327 		Aact.reset();
1328 #else
1329 		Aact = nullptr;
1330 #endif
1331 	}
1332 }
1333 
1334 void SlaOutputDev::startDoc(PDFDoc *doc, XRef *xrefA, Catalog *catA)
1335 {
1336 	xref = xrefA;
1337 	catalog = catA;
1338 	pdfDoc = doc;
1339 	updateGUICounter = 0;
1340 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 84, 0)
1341 	m_fontEngine = new SplashFontEngine(true, false, false, true);
1342 #else
1343 	m_fontEngine = new SplashFontEngine(globalParams->getEnableFreeType(), false, false, true);
1344 #endif
1345 }
1346 
1347 void SlaOutputDev::startPage(int pageNum, GfxState *, XRef *)
1348 {
1349 	m_formWidgets = pdfDoc->getPage(pageNum)->getFormWidgets();
1350 	m_radioMap.clear();
1351 	m_radioButtons.clear();
1352 	m_actPage = pageNum;
1353 	m_groupStack.clear();
1354 	pushGroup();
1355 	m_currentClipPath = QPainterPath();
1356 	m_clipPaths.clear();
1357 }
1358 
1359 void SlaOutputDev::endPage()
1360 {
1361 	if (!m_radioMap.isEmpty())
1362 	{
1363 		for (auto it = m_radioMap.begin(); it != m_radioMap.end(); ++it)
1364 		{
1365 			tmpSel->clear();
1366 			QList<int> refList = it.value();
1367 			for (int a = 0; a < refList.count(); a++)
1368 			{
1369 				if (m_radioButtons.contains(refList[a]))
1370 				{
1371 					tmpSel->addItem(m_radioButtons[refList[a]], true);
1372 					m_Elements->removeAll(m_radioButtons[refList[a]]);
1373 				}
1374 			}
1375 			if (!tmpSel->isEmpty())
1376 			{
1377 				PageItem *ite = m_doc->groupObjectsSelection(tmpSel);
1378 				ite->setItemName(it.key());
1379 				m_Elements->append(ite);
1380 				if (m_groupStack.count() != 0)
1381 					m_groupStack.top().Items.append(ite);
1382 			}
1383 		}
1384 	}
1385 	m_radioMap.clear();
1386 	m_radioButtons.clear();
1387 //	qDebug() << "ending page";
1388 }
1389 
1390 void SlaOutputDev::saveState(GfxState *state)
1391 {
1392 	m_clipPaths.push(m_currentClipPath);
1393 	pushGroup();
1394 }
1395 
1396 void SlaOutputDev::restoreState(GfxState *state)
1397 {
1398 	if (m_groupStack.count() != 0)
1399 	{
1400 		groupEntry gElements = m_groupStack.pop();
1401 		if (gElements.Items.count() > 0)
1402 		{
1403 			if ((gElements.Items.count() > 1) && (checkClip()))
1404 			{
1405 				tmpSel->clear();
1406 				for (int dre = 0; dre < gElements.Items.count(); ++dre)
1407 				{
1408 					tmpSel->addItem(gElements.Items.at(dre), true);
1409 					m_Elements->removeAll(gElements.Items.at(dre));
1410 				}
1411 				PageItem *ite = m_doc->groupObjectsSelection(tmpSel);
1412 				if (ite)
1413 				{
1414 					QPainterPath clippath = m_currentClipPath;
1415 					clippath.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
1416 					clippath.translate(-ite->xPos(), -ite->yPos());
1417 					ite->PoLine.fromQPainterPath(clippath, true);
1418 					ite->ClipEdited = true;
1419 					ite->FrameType = 3;
1420 					ite->setTextFlowMode(PageItem::TextFlowDisabled);
1421 					// Comment out temporarily, there are some bad interactions between adjustItemSize() and
1422 					// resizeGroupToContents() since fixing resizing of multiple selections
1423 					//m_doc->adjustItemSize(ite, true);
1424 					m_doc->resizeGroupToContents(ite);
1425 					ite->OldB2 = ite->width();
1426 					ite->OldH2 = ite->height();
1427 					m_Elements->append(ite);
1428 					if (m_groupStack.count() != 0)
1429 					{
1430 						applyMask(ite);
1431 						m_groupStack.top().Items.append(ite);
1432 					}
1433 				}
1434 				else
1435 				{
1436 					if (m_groupStack.count() != 0)
1437 					{
1438 						for (int dre = 0; dre < gElements.Items.count(); ++dre)
1439 						{
1440 							PageItem *ite = gElements.Items.at(dre);
1441 							applyMask(ite);
1442 							m_groupStack.top().Items.append(ite);
1443 						}
1444 					}
1445 				}
1446 				tmpSel->clear();
1447 			}
1448 			else
1449 			{
1450 				if (m_groupStack.count() != 0)
1451 				{
1452 					for (int dre = 0; dre < gElements.Items.count(); ++dre)
1453 					{
1454 						PageItem *ite = gElements.Items.at(dre);
1455 						applyMask(ite);
1456 						m_groupStack.top().Items.append(ite);
1457 					}
1458 				}
1459 			}
1460 		}
1461 	}
1462 	if (m_clipPaths.count() != 0)
1463 		m_currentClipPath = m_clipPaths.pop();
1464 }
1465 
1466 void SlaOutputDev::beginTransparencyGroup(GfxState *state, POPPLER_CONST_070 double *bbox, GfxColorSpace * /*blendingColorSpace*/, GBool isolated, GBool knockout, GBool forSoftMask)
1467 {
1468 // 	qDebug() << "SlaOutputDev::beginTransparencyGroup isolated:" << isolated << "knockout:" << knockout << "forSoftMask:" << forSoftMask;
1469 	pushGroup("", forSoftMask);
1470 	m_groupStack.top().isolated = isolated;
1471 }
1472 
1473 void SlaOutputDev::paintTransparencyGroup(GfxState *state, POPPLER_CONST_070 double *bbox)
1474 {
1475 // 	qDebug() << "SlaOutputDev::paintTransparencyGroup";
1476 	if (m_groupStack.count() != 0)
1477 	{
1478 		if ((m_groupStack.top().Items.count() != 0) && (!m_groupStack.top().forSoftMask))
1479 		{
1480 			PageItem *ite = m_groupStack.top().Items.last();
1481 			ite->setFillTransparency(1.0 - state->getFillOpacity());
1482 			ite->setFillBlendmode(getBlendMode(state));
1483 		}
1484 	}
1485 }
1486 
1487 void SlaOutputDev::endTransparencyGroup(GfxState *state)
1488 {
1489 // 	qDebug() << "SlaOutputDev::endTransparencyGroup";
1490 	if (m_groupStack.count() <= 0)
1491 		return;
1492 
1493 	tmpSel->clear();
1494 
1495 	groupEntry gElements = m_groupStack.pop();
1496 	if (gElements.Items.count() <= 0)
1497 		return;
1498 
1499 	if (gElements.forSoftMask)
1500 	{
1501 		for (int dre = 0; dre < gElements.Items.count(); ++dre)
1502 		{
1503 			tmpSel->addItem(gElements.Items.at(dre), true);
1504 			m_Elements->removeAll(gElements.Items.at(dre));
1505 		}
1506 		PageItem *ite = m_doc->groupObjectsSelection(tmpSel);
1507 		ite->setFillTransparency(1.0 - state->getFillOpacity());
1508 		ite->setFillBlendmode(getBlendMode(state));
1509 		ScPattern pat = ScPattern();
1510 		pat.setDoc(m_doc);
1511 		m_doc->DoDrawing = true;
1512 		pat.pattern = ite->DrawObj_toImage(qMin(qMax(ite->width(), ite->height()), 500.0));
1513 		pat.xoffset = 0;
1514 		pat.yoffset = 0;
1515 		m_doc->DoDrawing = false;
1516 		pat.width = ite->width();
1517 		pat.height = ite->height();
1518 		m_currentMaskPosition = QPointF(ite->xPos(), ite->yPos());
1519 		ite->gXpos = 0;
1520 		ite->gYpos = 0;
1521 		ite->setXYPos(ite->gXpos, ite->gYpos, true);
1522 		pat.items.append(ite);
1523 		m_doc->Items->removeAll(ite);
1524 		QString id = QString("Pattern_from_PDF_%1S").arg(m_doc->docPatterns.count() + 1);
1525 		m_doc->addPattern(id, pat);
1526 		m_currentMask = id;
1527 		tmpSel->clear();
1528 		return;
1529 	}
1530 	PageItem *ite;
1531 	for (int dre = 0; dre < gElements.Items.count(); ++dre)
1532 	{
1533 		tmpSel->addItem(gElements.Items.at(dre), true);
1534 		m_Elements->removeAll(gElements.Items.at(dre));
1535 	}
1536 	if ((gElements.Items.count() != 1) || (gElements.isolated))
1537 		ite = m_doc->groupObjectsSelection(tmpSel);
1538 	else
1539 		ite = gElements.Items.first();
1540 	if (ite->isGroup())
1541 	{
1542 		ite->ClipEdited = true;
1543 		ite->FrameType = 3;
1544 		if (checkClip())
1545 		{
1546 			QPainterPath clippath = m_currentClipPath;
1547 			clippath.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
1548 			clippath.translate(-ite->xPos(), -ite->yPos());
1549 			ite->PoLine.fromQPainterPath(clippath, true);
1550 			ite->ClipEdited = true;
1551 			ite->FrameType = 3;
1552 			ite->setTextFlowMode(PageItem::TextFlowDisabled);
1553 			// Comment out temporarily, there are some bad interactions between adjustItemSize() and
1554 			// resizeGroupToContents() since fixing resizing of multiple selections
1555 			//m_doc->adjustItemSize(ite, true);
1556 			m_doc->resizeGroupToContents(ite);
1557 			ite->OldB2 = ite->width();
1558 			ite->OldH2 = ite->height();
1559 		}
1560 	}
1561 	ite->setFillTransparency(1.0 - state->getFillOpacity());
1562 	ite->setFillBlendmode(getBlendMode(state));
1563 	m_Elements->append(ite);
1564 	if (m_groupStack.count() != 0)
1565 	{
1566 		applyMask(ite);
1567 		m_groupStack.top().Items.append(ite);
1568 	}
1569 
1570 	tmpSel->clear();
1571 }
1572 
1573 void SlaOutputDev::setSoftMask(GfxState * /*state*/, POPPLER_CONST_070 double * bbox, GBool alpha, Function *transferFunc, GfxColor * /*backdropColor*/)
1574 {
1575 	if (m_groupStack.count() <= 0)
1576 		return;
1577 
1578 	double lum = 0;
1579 	double lum2 = 0;
1580 	if (transferFunc)
1581 		transferFunc->transform(&lum, &lum2);
1582 	else
1583 		lum2 = lum;
1584 	m_groupStack.top().inverted = (lum != lum2);
1585 	m_groupStack.top().maskName = m_currentMask;
1586 	// Remember the mask's position as it might not align with the image to which the mask is later assigned.
1587 	m_groupStack.top().maskPos = m_currentMaskPosition;
1588 	m_groupStack.top().alpha = alpha;
1589 	if (m_groupStack.top().Items.count() != 0)
1590 		applyMask(m_groupStack.top().Items.last());
1591 }
1592 
1593 void SlaOutputDev::clearSoftMask(GfxState * /*state*/)
1594 {
1595 	if (m_groupStack.count() != 0)
1596 		m_groupStack.top().maskName = "";
1597 }
1598 
1599 void SlaOutputDev::updateFillColor(GfxState *state)
1600 {
1601 	m_currFillShade = 100;
1602 	m_currColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &m_currFillShade);
1603 }
1604 
1605 void SlaOutputDev::updateStrokeColor(GfxState *state)
1606 {
1607 	m_currStrokeShade = 100;
1608 	m_currColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &m_currStrokeShade);
1609 }
1610 
1611 void SlaOutputDev::clip(GfxState *state)
1612 {
1613 //	qDebug() << "Clip";
1614 	adjustClip(state, Qt::WindingFill);
1615 }
1616 
1617 void SlaOutputDev::eoClip(GfxState *state)
1618 {
1619 //	qDebug() << "EoClip";
1620 	adjustClip(state, Qt::OddEvenFill);
1621 }
1622 
1623 void SlaOutputDev::adjustClip(GfxState *state, Qt::FillRule fillRule)
1624 {
1625 	const double *ctm = state->getCTM();
1626 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
1627 	QString output = convertPath(state->getPath());
1628 	if (output.isEmpty())
1629 		return;
1630 	FPointArray out;
1631 	out.parseSVG(output);
1632 	out.svgClosePath();
1633 	out.map(m_ctm);
1634 	if (checkClip())
1635 	{
1636 		// "clip" (WindingFill) and "eoClip" (OddEvenFill) only the determine
1637 		// the fill rule of the new clipping path. The new clip should be the
1638 		// intersection of the old and new area. QPainterPath determines on
1639 		// its own which fill rule to use for the result. We should not loose
1640 		// this information.
1641 		QPainterPath pathN = out.toQPainterPath(false);
1642 		pathN.setFillRule(fillRule);
1643 		m_currentClipPath = intersection(pathN, m_currentClipPath);
1644 	}
1645 	else
1646 		m_currentClipPath = out.toQPainterPath(false);
1647 }
1648 
1649 void SlaOutputDev::stroke(GfxState *state)
1650 {
1651 //	qDebug() << "Stroke";
1652 	const double *ctm;
1653 	ctm = state->getCTM();
1654 	double xCoor = m_doc->currentPage()->xOffset();
1655 	double yCoor = m_doc->currentPage()->yOffset();
1656 	QString output = convertPath(state->getPath());
1657 	getPenState(state);
1658 	if ((m_Elements->count() != 0) && (output == Coords))			// Path is the same as in last fill
1659 	{
1660 		PageItem* ite = m_Elements->last();
1661 		ite->setLineColor(m_currColorStroke);
1662 		ite->setLineShade(m_currStrokeShade);
1663 		ite->setLineEnd(m_lineEnd);
1664 		ite->setLineJoin(m_lineJoin);
1665 		ite->setLineWidth(state->getTransformedLineWidth());
1666 		ite->setDashes(DashValues);
1667 		ite->setDashOffset(DashOffset);
1668 		ite->setLineTransparency(1.0 - state->getStrokeOpacity());
1669 	}
1670 	else
1671 	{
1672 		FPointArray out;
1673 		out.parseSVG(output);
1674 		m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
1675 		out.map(m_ctm);
1676 		FPoint wh = out.widthHeight();
1677 		if ((out.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0)))
1678 		{
1679 			m_currColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &m_currStrokeShade);
1680 			int z;
1681 			if (pathIsClosed)
1682 				z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, state->getTransformedLineWidth(), CommonStrings::None, m_currColorStroke);
1683 			else
1684 				z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, state->getTransformedLineWidth(), CommonStrings::None, m_currColorStroke);
1685 			PageItem* ite = m_doc->Items->at(z);
1686 			ite->PoLine = out.copy();
1687 			ite->ClipEdited = true;
1688 			ite->FrameType = 3;
1689 			ite->setWidthHeight(wh.x(), wh.y());
1690 			m_doc->adjustItemSize(ite);
1691 			if (m_Elements->count() != 0)
1692 			{
1693 				PageItem* lItem = m_Elements->last();
1694 				if ((lItem->lineColor() == CommonStrings::None) && (lItem->PoLine == ite->PoLine))
1695 				{
1696 					lItem->setLineColor(m_currColorStroke);
1697 					lItem->setLineWidth(state->getTransformedLineWidth());
1698 					lItem->setLineShade(m_currStrokeShade);
1699 					lItem->setLineTransparency(1.0 - state->getStrokeOpacity());
1700 					lItem->setLineBlendmode(getBlendMode(state));
1701 					lItem->setLineEnd(m_lineEnd);
1702 					lItem->setLineJoin(m_lineJoin);
1703 					lItem->setDashes(DashValues);
1704 					lItem->setDashOffset(DashOffset);
1705 					lItem->setTextFlowMode(PageItem::TextFlowDisabled);
1706 					m_doc->Items->removeAll(ite);
1707 				}
1708 				else
1709 				{
1710 					ite->setLineShade(m_currStrokeShade);
1711 					ite->setLineTransparency(1.0 - state->getStrokeOpacity());
1712 					ite->setLineBlendmode(getBlendMode(state));
1713 					ite->setLineEnd(m_lineEnd);
1714 					ite->setLineJoin(m_lineJoin);
1715 					ite->setDashes(DashValues);
1716 					ite->setDashOffset(DashOffset);
1717 					ite->setTextFlowMode(PageItem::TextFlowDisabled);
1718 					m_Elements->append(ite);
1719 					if (m_groupStack.count() != 0)
1720 						m_groupStack.top().Items.append(ite);
1721 				}
1722 			}
1723 			else
1724 			{
1725 				ite->setLineShade(m_currStrokeShade);
1726 				ite->setLineTransparency(1.0 - state->getStrokeOpacity());
1727 				ite->setLineBlendmode(getBlendMode(state));
1728 				ite->setLineEnd(m_lineEnd);
1729 				ite->setLineJoin(m_lineJoin);
1730 				ite->setDashes(DashValues);
1731 				ite->setDashOffset(DashOffset);
1732 				ite->setTextFlowMode(PageItem::TextFlowDisabled);
1733 				m_Elements->append(ite);
1734 				if (m_groupStack.count() != 0)
1735 					m_groupStack.top().Items.append(ite);
1736 			}
1737 		}
1738 	}
1739 }
1740 
1741 void SlaOutputDev::fill(GfxState *state)
1742 {
1743 //	qDebug() << "Fill";
1744 	createFillItem(state, Qt::WindingFill);
1745 }
1746 
1747 void SlaOutputDev::eoFill(GfxState *state)
1748 {
1749 //	qDebug() << "EoFill";
1750 	createFillItem(state, Qt::OddEvenFill);
1751 }
1752 
1753 void SlaOutputDev::createFillItem(GfxState *state, Qt::FillRule fillRule)
1754 {
1755 	const double *ctm;
1756 	ctm = state->getCTM();
1757 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
1758 	double xCoor = m_doc->currentPage()->xOffset();
1759 	double yCoor = m_doc->currentPage()->yOffset();
1760 	FPointArray out;
1761 	QString output = convertPath(state->getPath());
1762 	out.parseSVG(output);
1763 	out.map(m_ctm);
1764 
1765 	// Clip the new path first and only add it if it is not empty.
1766 	QPainterPath path = out.toQPainterPath(false);
1767 	path.setFillRule(fillRule);
1768 	QPainterPath clippedPath = intersection(m_currentClipPath, path);
1769 
1770 	// Undo the rotation of the clipping path as it is rotated together with the item.
1771 	double angle = m_ctm.map(QLineF(0, 0, 1, 0)).angle();
1772 	QTransform mm;
1773 	mm.rotate(angle);
1774 	clippedPath = mm.map(clippedPath);
1775 
1776 	Coords = output;
1777 	QRectF bbox = clippedPath.boundingRect();
1778 	if (!clippedPath.isEmpty() && !bbox.isNull())
1779 	{
1780 		m_currColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &m_currFillShade);
1781 		int z;
1782 		if (pathIsClosed)
1783 			z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, m_currColorFill, CommonStrings::None);
1784 		else
1785 			z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, m_currColorFill, CommonStrings::None);
1786 		PageItem* ite = m_doc->Items->at(z);
1787 		ite->PoLine.fromQPainterPath(clippedPath, true);
1788 		ite->ClipEdited = true;
1789 		ite->FrameType = 3;
1790 		ite->setFillShade(m_currFillShade);
1791 		ite->setLineShade(100);
1792 		ite->setRotation(-angle);
1793 		// Only the new path has to be interpreted according to fillRule. QPainterPath
1794 		// could decide to create a final path according to the other rule. Thus
1795 		// we have to set this from the final path.
1796 		ite->setFillEvenOdd(clippedPath.fillRule() == Qt::OddEvenFill);
1797 		ite->setFillTransparency(1.0 - state->getFillOpacity());
1798 		ite->setFillBlendmode(getBlendMode(state));
1799 		ite->setLineEnd(m_lineEnd);
1800 		ite->setLineJoin(m_lineJoin);
1801 		ite->setWidthHeight(bbox.width(),bbox.height());
1802 		ite->setTextFlowMode(PageItem::TextFlowDisabled);
1803 		m_doc->adjustItemSize(ite);
1804 		m_Elements->append(ite);
1805 		if (m_groupStack.count() != 0)
1806 		{
1807 			m_groupStack.top().Items.append(ite);
1808 			applyMask(ite);
1809 		}
1810 	}
1811 }
1812 
1813 GBool SlaOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax)
1814 {
1815 //	qDebug() << "SlaOutputDev::axialShadedFill";
1816 	double GrStartX;
1817 	double GrStartY;
1818 	double GrEndX;
1819 	double GrEndY;
1820 	int shade = 100;
1821 	POPPLER_CONST_070 Function *func = shading->getFunc(0);
1822 	VGradient FillGradient = VGradient(VGradient::linear);
1823 	FillGradient.clearStops();
1824 	GfxColorSpace *color_space = shading->getColorSpace();
1825 	if (func->getType() == 3)
1826 	{
1827 		StitchingFunction *stitchingFunc = (StitchingFunction*)func;
1828 		const double *bounds = stitchingFunc->getBounds();
1829 		int num_funcs = stitchingFunc->getNumFuncs();
1830 		double domain_min = stitchingFunc->getDomainMin(0);
1831 		double domain_max = stitchingFunc->getDomainMax(0);
1832 		if (fabs(domain_max - domain_min) < 1e-6)
1833 		{
1834 			domain_min = 0.0;
1835 			domain_max = 1.0;
1836 		}
1837 		// Add stops from all the stitched functions
1838 		for (int i = 0 ; i <= num_funcs ; i++)
1839 		{
1840 			GfxColor temp;
1841 			shading->getColor(bounds[i], &temp);
1842 			QString stopColor = getColor(color_space, &temp, &shade);
1843 			double stopPoint = (bounds[i] - domain_min) / (domain_max - domain_min);
1844 			FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor], m_doc, shade), stopPoint, 0.5, 1.0, stopColor, shade );
1845 		}
1846 	}
1847 	else if ((func->getType() == 2) || (func->getType() == 0))
1848 	{
1849 		GfxColor stop1;
1850 		shading->getColor(0.0, &stop1);
1851 		QString stopColor1 = getColor(color_space, &stop1, &shade);
1852 		FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor1], m_doc, shade), 0.0, 0.5, 1.0, stopColor1, shade );
1853 		GfxColor stop2;
1854 		shading->getColor(1.0, &stop2);
1855 		QString stopColor2 = getColor(color_space, &stop2, &shade);
1856 		FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor2], m_doc, shade), 1.0, 0.5, 1.0, stopColor2, shade );
1857 	}
1858 	shading->getCoords(&GrStartX, &GrStartY, &GrEndX, &GrEndY);
1859 	double xmin, ymin, xmax, ymax;
1860 	// get the clip region bbox
1861 	state->getClipBBox(&xmin, &ymin, &xmax, &ymax);
1862 	QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax));
1863 	crect = crect.normalized();
1864 	QPainterPath out;
1865 	out.addRect(crect);
1866 	if (checkClip())
1867 	{
1868 		// Apply the clip path early to adjust the gradient vector to the
1869 		// smaller boundign box.
1870 		out = intersection(m_currentClipPath, out);
1871 		crect = out.boundingRect();
1872 	}
1873 	const double *ctm = state->getCTM();
1874 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
1875 	FPointArray gr;
1876 	gr.addPoint(GrStartX, GrStartY);
1877 	gr.addPoint(GrEndX, GrEndY);
1878 	gr.map(m_ctm);
1879 	gr.translate(-crect.x(), -crect.y());
1880 
1881 	// Undo the rotation and translation of the gradient vector.
1882 	double angle = m_ctm.map(QLineF(0, 0, 1, 0)).angle();
1883 	QTransform mm;
1884 	mm.rotate(angle);
1885 	out.translate(-crect.x(), -crect.y());
1886 	out = mm.map(out);
1887 	QRectF bb = out.boundingRect();
1888 	gr.map(mm);
1889 	gr.translate(-bb.left(), -bb.top());
1890 	GrStartX = gr.point(0).x();
1891 	GrStartY = gr.point(0).y();
1892 	GrEndX = gr.point(1).x();
1893 	GrEndY = gr.point(1).y();
1894 
1895 	double xCoor = m_doc->currentPage()->xOffset();
1896 	double yCoor = m_doc->currentPage()->yOffset();
1897 	QString output = QString("M %1 %2").arg(0.0).arg(0.0);
1898 	output += QString("L %1 %2").arg(crect.width()).arg(0.0);
1899 	output += QString("L %1 %2").arg(crect.width()).arg(crect.height());
1900 	output += QString("L %1 %2").arg(0.0).arg(crect.height());
1901 	output += QString("L %1 %2").arg(0.0).arg(0.0);
1902 	output += QString("Z");
1903 	pathIsClosed = true;
1904 	Coords = output;
1905 	int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), bb.width(), bb.height(), 0, m_currColorFill, CommonStrings::None);
1906 	PageItem* ite = m_doc->Items->at(z);
1907 	if (checkClip())
1908 	{
1909 		ite->PoLine.fromQPainterPath(out, true);
1910 		ite->setFillEvenOdd(out.fillRule() == Qt::OddEvenFill);
1911 	}
1912 	ite->setRotation(-angle);
1913 	ite->ClipEdited = true;
1914 	ite->FrameType = 3;
1915 	ite->setFillShade(m_currFillShade);
1916 	ite->setLineShade(100);
1917 	ite->setFillTransparency(1.0 - state->getFillOpacity());
1918 	ite->setFillBlendmode(getBlendMode(state));
1919 	ite->setLineEnd(m_lineEnd);
1920 	ite->setLineJoin(m_lineJoin);
1921 	ite->setTextFlowMode(PageItem::TextFlowDisabled);
1922 	ite->GrType = 6;
1923 	if (!shading->getExtend0() || !shading->getExtend1())
1924 	{
1925 		FillGradient.setRepeatMethod(VGradient::none);
1926 		ite->setGradientExtend(VGradient::none);
1927 	}
1928 	else
1929 	{
1930 		FillGradient.setRepeatMethod(VGradient::pad);
1931 		ite->setGradientExtend(VGradient::pad);
1932 	}
1933 	ite->fill_gradient = FillGradient;
1934 	ite->setGradientVector(GrStartX, GrStartY, GrEndX, GrEndY, 0, 0, 1, 0);
1935 	m_doc->adjustItemSize(ite);
1936 	m_Elements->append(ite);
1937 	if (m_groupStack.count() != 0)
1938 	{
1939 		m_groupStack.top().Items.append(ite);
1940 		applyMask(ite);
1941 	}
1942 	return gTrue;
1943 }
1944 
1945 GBool SlaOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax)
1946 {
1947 //	qDebug() << "SlaOutputDev::radialShadedFill";
1948 	double GrStartX;
1949 	double GrStartY;
1950 	double GrEndX;
1951 	double GrEndY;
1952 	int shade = 100;
1953 	POPPLER_CONST_070 Function *func = shading->getFunc(0);
1954 	VGradient FillGradient = VGradient(VGradient::linear);
1955 	FillGradient.clearStops();
1956 	GfxColorSpace *color_space = shading->getColorSpace();
1957 	if (func->getType() == 3)
1958 	{
1959 		StitchingFunction *stitchingFunc = (StitchingFunction*)func;
1960 		const double *bounds = stitchingFunc->getBounds();
1961 		int num_funcs = stitchingFunc->getNumFuncs();
1962 		double domain_min = stitchingFunc->getDomainMin(0);
1963 		double domain_max = stitchingFunc->getDomainMax(0);
1964 		if (fabs(domain_max - domain_min) < 1e-6)
1965 		{
1966 			domain_min = 0.0;
1967 			domain_max = 1.0;
1968 		}
1969 		// Add stops from all the stitched functions
1970 		for (int i = 0 ; i <= num_funcs ; i++)
1971 		{
1972 			GfxColor temp;
1973 			shading->getColor(bounds[i], &temp);
1974 			QString stopColor = getColor(color_space, &temp, &shade);
1975 			double stopPoint = (bounds[i] - domain_min) / (domain_max - domain_min);
1976 			FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor], m_doc, shade), stopPoint, 0.5, 1.0, stopColor, shade );
1977 		}
1978 	}
1979 	else if ((func->getType() == 2) || (func->getType() == 0))
1980 	{
1981 		GfxColor stop1;
1982 		shading->getColor(0.0, &stop1);
1983 		QString stopColor1 = getColor(color_space, &stop1, &shade);
1984 		FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor1], m_doc, shade), 0.0, 0.5, 1.0, stopColor1, shade );
1985 		GfxColor stop2;
1986 		shading->getColor(1.0, &stop2);
1987 		QString stopColor2 = getColor(color_space, &stop2, &shade);
1988 		FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor2], m_doc, shade), 1.0, 0.5, 1.0, stopColor2, shade );
1989 	}
1990 	double r0, x1, y1, r1;
1991 	shading->getCoords(&GrStartX, &GrStartY, &r0, &x1, &y1, &r1);
1992 	double xmin, ymin, xmax, ymax;
1993 	// get the clip region bbox
1994 	state->getClipBBox(&xmin, &ymin, &xmax, &ymax);
1995 	QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax));
1996 	crect = crect.normalized();
1997 	double GrFocalX = x1;
1998 	double GrFocalY = y1;
1999 	GrEndX = GrFocalX + r1;
2000 	GrEndY = GrFocalY;
2001 	const double *ctm = state->getCTM();
2002 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
2003 	FPointArray gr;
2004 	gr.addPoint(GrStartX, GrStartY);
2005 	gr.addPoint(GrEndX, GrEndY);
2006 	gr.addPoint(GrFocalX, GrFocalY);
2007 	gr.map(m_ctm);
2008 	GrStartX = gr.point(0).x() - crect.x();
2009 	GrStartY = gr.point(0).y() - crect.y();
2010 	GrEndX = gr.point(1).x() - crect.x();
2011 	GrEndY = gr.point(1).y() - crect.y();
2012 	GrFocalX = gr.point(2).x() - crect.x();
2013 	GrFocalY = gr.point(2).y() - crect.y();
2014 	double xCoor = m_doc->currentPage()->xOffset();
2015 	double yCoor = m_doc->currentPage()->yOffset();
2016 	QString output = QString("M %1 %2").arg(0.0).arg(0.0);
2017 	output += QString("L %1 %2").arg(crect.width()).arg(0.0);
2018 	output += QString("L %1 %2").arg(crect.width()).arg(crect.height());
2019 	output += QString("L %1 %2").arg(0.0).arg(crect.height());
2020 	output += QString("L %1 %2").arg(0.0).arg(0.0);
2021 	output += QString("Z");
2022 	pathIsClosed = true;
2023 	Coords = output;
2024 	int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, m_currColorFill, CommonStrings::None);
2025 	PageItem* ite = m_doc->Items->at(z);
2026 	if (checkClip())
2027 	{
2028 		QPainterPath out = m_currentClipPath;
2029 		out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset());
2030 		out.translate(-ite->xPos(), -ite->yPos());
2031 		ite->PoLine.fromQPainterPath(out, true);
2032 		ite->setFillEvenOdd(out.fillRule() == Qt::OddEvenFill);
2033 	}
2034 	ite->ClipEdited = true;
2035 	ite->FrameType = 3;
2036 	ite->setFillShade(m_currFillShade);
2037 	ite->setLineShade(100);
2038 	ite->setFillTransparency(1.0 - state->getFillOpacity());
2039 	ite->setFillBlendmode(getBlendMode(state));
2040 	ite->setLineEnd(m_lineEnd);
2041 	ite->setLineJoin(m_lineJoin);
2042 	ite->setTextFlowMode(PageItem::TextFlowDisabled);
2043 	ite->GrType = 7;
2044 	if (!shading->getExtend0() || !shading->getExtend1())
2045 	{
2046 		FillGradient.setRepeatMethod(VGradient::none);
2047 		ite->setGradientExtend(VGradient::none);
2048 	}
2049 	else
2050 	{
2051 		FillGradient.setRepeatMethod(VGradient::pad);
2052 		ite->setGradientExtend(VGradient::pad);
2053 	}
2054 	ite->fill_gradient = FillGradient;
2055 	ite->setGradientVector(GrStartX, GrStartY, GrEndX, GrEndY, GrFocalX, GrFocalY, 1, 0);
2056 	m_doc->adjustItemSize(ite);
2057 	m_Elements->append(ite);
2058 	if (m_groupStack.count() != 0)
2059 	{
2060 		m_groupStack.top().Items.append(ite);
2061 		applyMask(ite);
2062 	}
2063 	return gTrue;
2064 }
2065 
2066 GBool SlaOutputDev::gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading)
2067 {
2068 //	qDebug() << "SlaOutputDev::gouraudTriangleShadedFill";
2069 	double xCoor = m_doc->currentPage()->xOffset();
2070 	double yCoor = m_doc->currentPage()->yOffset();
2071 	double xmin, ymin, xmax, ymax;
2072 	// get the clip region bbox
2073 	state->getClipBBox(&xmin, &ymin, &xmax, &ymax);
2074 	QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax));
2075 	crect = crect.normalized();
2076 	QString output = QString("M %1 %2").arg(0.0).arg(0.0);
2077 	output += QString("L %1 %2").arg(crect.width()).arg(0.0);
2078 	output += QString("L %1 %2").arg(crect.width()).arg(crect.height());
2079 	output += QString("L %1 %2").arg(0.0).arg(crect.height());
2080 	output += QString("L %1 %2").arg(0.0).arg(0.0);
2081 	output += QString("Z");
2082 	pathIsClosed = true;
2083 	Coords = output;
2084 	const double *ctm = state->getCTM();
2085 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
2086 	int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, m_currColorFill, CommonStrings::None);
2087 	PageItem* ite = m_doc->Items->at(z);
2088 	ite->ClipEdited = true;
2089 	ite->FrameType = 3;
2090 	ite->setFillShade(m_currFillShade);
2091 	ite->setLineShade(100);
2092 	ite->setFillEvenOdd(false);
2093 	ite->setFillTransparency(1.0 - state->getFillOpacity());
2094 	ite->setFillBlendmode(getBlendMode(state));
2095 	ite->setLineEnd(m_lineEnd);
2096 	ite->setLineJoin(m_lineJoin);
2097 	ite->setTextFlowMode(PageItem::TextFlowDisabled);
2098 	m_doc->adjustItemSize(ite);
2099 	m_Elements->append(ite);
2100 	if (m_groupStack.count() != 0)
2101 	{
2102 		m_groupStack.top().Items.append(ite);
2103 		applyMask(ite);
2104 	}
2105 	GfxColor color[3];
2106 	double x0, y0, x1, y1, x2, y2;
2107 	for (int i = 0; i < shading->getNTriangles(); i++)
2108 	{
2109 		int shade = 100;
2110 		meshGradientPatch patchM;
2111 		shading->getTriangle(i, &x0, &y0, &color[0],  &x1, &y1, &color[1],  &x2, &y2, &color[2]);
2112 		patchM.BL.resetTo(FPoint(x0, y0));
2113 		patchM.BL.shade = 100;
2114 		patchM.BL.transparency = 1.0;
2115 		patchM.BL.colorName = getColor(shading->getColorSpace(), &color[0], &shade);
2116 		patchM.BL.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.BL.colorName], m_doc, shade);
2117 		patchM.TL.resetTo(FPoint(x1, y1));
2118 		patchM.TL.shade = 100;
2119 		patchM.TL.transparency = 1.0;
2120 		patchM.TL.colorName = getColor(shading->getColorSpace(), &color[1], &shade);
2121 		patchM.TL.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.TL.colorName], m_doc, shade);
2122 		patchM.TR.resetTo(FPoint(x2, y2));
2123 		patchM.TR.shade = 100;
2124 		patchM.TR.transparency = 1.0;
2125 		patchM.TR.colorName = getColor(shading->getColorSpace(), &color[2], &shade);
2126 		patchM.TR.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.TR.colorName], m_doc, shade);
2127 		patchM.BR.resetTo(FPoint(x0, y0));
2128 		patchM.BR.shade = 100;
2129 		patchM.BR.transparency = 1.0;
2130 		patchM.BR.colorName = getColor(shading->getColorSpace(), &color[0], &shade);
2131 		patchM.BR.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.BR.colorName], m_doc, shade);
2132 		patchM.TL.transform(m_ctm);
2133 		patchM.TL.moveRel(-crect.x(), -crect.y());
2134 		patchM.TR.transform(m_ctm);
2135 		patchM.TR.moveRel(-crect.x(), -crect.y());
2136 		patchM.BR.transform(m_ctm);
2137 		patchM.BR.moveRel(-crect.x(), -crect.y());
2138 		patchM.BL.transform(m_ctm);
2139 		patchM.BL.moveRel(-crect.x(), -crect.y());
2140 		ite->meshGradientPatches.append(patchM);
2141 	}
2142 	ite->GrType = 12;
2143 	return gTrue;
2144 }
2145 
2146 GBool SlaOutputDev::patchMeshShadedFill(GfxState *state, GfxPatchMeshShading *shading)
2147 {
2148 //	qDebug() << "SlaOutputDev::patchMeshShadedFill";
2149 	double xCoor = m_doc->currentPage()->xOffset();
2150 	double yCoor = m_doc->currentPage()->yOffset();
2151 	double xmin, ymin, xmax, ymax;
2152 	// get the clip region bbox
2153 	state->getClipBBox(&xmin, &ymin, &xmax, &ymax);
2154 	QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax));
2155 	crect = crect.normalized();
2156 	QString output = QString("M %1 %2").arg(0.0).arg(0.0);
2157 	output += QString("L %1 %2").arg(crect.width()).arg(0.0);
2158 	output += QString("L %1 %2").arg(crect.width()).arg(crect.height());
2159 	output += QString("L %1 %2").arg(0.0).arg(crect.height());
2160 	output += QString("L %1 %2").arg(0.0).arg(0.0);
2161 	output += QString("Z");
2162 	pathIsClosed = true;
2163 	Coords = output;
2164 	const double *ctm = state->getCTM();
2165 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
2166 	int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, m_currColorFill, CommonStrings::None);
2167 	PageItem* ite = m_doc->Items->at(z);
2168 	ite->ClipEdited = true;
2169 	ite->FrameType = 3;
2170 	ite->setFillShade(m_currFillShade);
2171 	ite->setLineShade(100);
2172 	ite->setFillEvenOdd(false);
2173 	ite->setFillTransparency(1.0 - state->getFillOpacity());
2174 	ite->setFillBlendmode(getBlendMode(state));
2175 	ite->setLineEnd(m_lineEnd);
2176 	ite->setLineJoin(m_lineJoin);
2177 	ite->setTextFlowMode(PageItem::TextFlowDisabled);
2178 	m_doc->adjustItemSize(ite);
2179 	m_Elements->append(ite);
2180 	if (m_groupStack.count() != 0)
2181 	{
2182 		m_groupStack.top().Items.append(ite);
2183 		applyMask(ite);
2184 	}
2185 	ite->meshGradientPatches.clear();
2186 	for (int i = 0; i < shading->getNPatches(); i++)
2187 	{
2188 		int shade = 100;
2189 		const GfxPatch *patch = shading->getPatch(i);
2190 		GfxColor color;
2191 		meshGradientPatch patchM;
2192 		int u, v;
2193 		patchM.BL.resetTo(FPoint(patch->x[0][0], patch->y[0][0]));
2194 		patchM.BL.controlTop = FPoint(patch->x[0][1], patch->y[0][1]);
2195 		patchM.BL.controlRight = FPoint(patch->x[1][0], patch->y[1][0]);
2196 		patchM.BL.controlColor = FPoint(patch->x[1][1], patch->y[1][1]);
2197 		u = 0;
2198 		v = 0;
2199 		if (shading->isParameterized())
2200 		{
2201 			shading->getParameterizedColor (patch->color[u][v].c[0], &color);
2202 		}
2203 		else
2204 		{
2205 			for (int k = 0; k < shading->getColorSpace()->getNComps(); k++)
2206 			{
2207 				color.c[k] = GfxColorComp (patch->color[u][v].c[k]);
2208 			}
2209 		}
2210 		patchM.BL.colorName = getColor(shading->getColorSpace(), &color, &shade);
2211 		patchM.BL.shade = 100;
2212 		patchM.BL.transparency = 1.0;
2213 		patchM.BL.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.BL.colorName], m_doc, shade);
2214 
2215 		u = 0;
2216 		v = 1;
2217 		patchM.TL.resetTo(FPoint(patch->x[0][3], patch->y[0][3]));
2218 		patchM.TL.controlRight = FPoint(patch->x[1][3], patch->y[1][3]);
2219 		patchM.TL.controlBottom = FPoint(patch->x[0][2], patch->y[0][2]);
2220 		patchM.TL.controlColor = FPoint(patch->x[1][2], patch->y[1][2]);
2221 		if (shading->isParameterized())
2222 		{
2223 			shading->getParameterizedColor (patch->color[u][v].c[0], &color);
2224 		}
2225 		else
2226 		{
2227 			for (int k = 0; k < shading->getColorSpace()->getNComps(); k++)
2228 			{
2229 				color.c[k] = GfxColorComp (patch->color[u][v].c[k]);
2230 			}
2231 		}
2232 		patchM.TL.colorName = getColor(shading->getColorSpace(), &color, &shade);
2233 		patchM.TL.shade = 100;
2234 		patchM.TL.transparency = 1.0;
2235 		patchM.TL.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.TL.colorName], m_doc, shade);
2236 
2237 		u = 1;
2238 		v = 1;
2239 		patchM.TR.resetTo(FPoint(patch->x[3][3], patch->y[3][3]));
2240 		patchM.TR.controlBottom = FPoint(patch->x[3][2], patch->y[3][2]);
2241 		patchM.TR.controlLeft = FPoint(patch->x[2][3], patch->y[2][3]);
2242 		patchM.TR.controlColor = FPoint(patch->x[2][2], patch->y[2][2]);
2243 		if (shading->isParameterized())
2244 		{
2245 			shading->getParameterizedColor (patch->color[u][v].c[0], &color);
2246 		}
2247 		else
2248 		{
2249 			for (int k = 0; k < shading->getColorSpace()->getNComps(); k++)
2250 			{
2251 				color.c[k] = GfxColorComp (patch->color[u][v].c[k]);
2252 			}
2253 		}
2254 		patchM.TR.colorName = getColor(shading->getColorSpace(), &color, &shade);
2255 		patchM.TR.shade = 100;
2256 		patchM.TR.transparency = 1.0;
2257 		patchM.TR.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.TR.colorName], m_doc, shade);
2258 
2259 		u = 1;
2260 		v = 0;
2261 		patchM.BR.resetTo(FPoint(patch->x[3][0], patch->y[3][0]));
2262 		patchM.BR.controlLeft = FPoint(patch->x[2][0], patch->y[2][0]);
2263 		patchM.BR.controlTop = FPoint(patch->x[3][1], patch->y[3][1]);
2264 		patchM.BR.controlColor = FPoint(patch->x[2][1], patch->y[2][1]);
2265 		if (shading->isParameterized())
2266 		{
2267 			shading->getParameterizedColor (patch->color[u][v].c[0], &color);
2268 		}
2269 		else
2270 		{
2271 			for (int k = 0; k < shading->getColorSpace()->getNComps(); k++)
2272 			{
2273 				color.c[k] = GfxColorComp (patch->color[u][v].c[k]);
2274 			}
2275 		}
2276 		patchM.BR.colorName = getColor(shading->getColorSpace(), &color, &shade);
2277 		patchM.BR.shade = 100;
2278 		patchM.BR.transparency = 1.0;
2279 		patchM.BR.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.BR.colorName], m_doc, shade);
2280 
2281 		patchM.TL.transform(m_ctm);
2282 		patchM.TL.moveRel(-crect.x(), -crect.y());
2283 		patchM.TR.transform(m_ctm);
2284 		patchM.TR.moveRel(-crect.x(), -crect.y());
2285 		patchM.BR.transform(m_ctm);
2286 		patchM.BR.moveRel(-crect.x(), -crect.y());
2287 		patchM.BL.transform(m_ctm);
2288 		patchM.BL.moveRel(-crect.x(), -crect.y());
2289 		ite->meshGradientPatches.append(patchM);
2290 	}
2291 	ite->GrType = 12;
2292 	return gTrue;
2293 }
2294 
2295 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(21, 3, 0)
2296 bool SlaOutputDev::tilingPatternFill(GfxState *state, Gfx * /*gfx*/, Catalog *cat, GfxTilingPattern *tPat, const double *mat, int x0, int y0, int x1, int y1, double xStep, double yStep)
2297 #else
2298 GBool SlaOutputDev::tilingPatternFill(GfxState *state, Gfx * /*gfx*/, Catalog *cat, Object *str, POPPLER_CONST_070 double *pmat, int /*paintType*/, int /*tilingType*/, Dict *resDict, POPPLER_CONST_070 double *mat, POPPLER_CONST_070 double *bbox, int x0, int y0, int x1, int y1, double xStep, double yStep)
2299 #endif
2300 {
2301 //	qDebug() << "SlaOutputDev::tilingPatternFill";
2302 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(21, 3, 0)
2303 	const double *bbox = tPat->getBBox();
2304 	const double *pmat = tPat->getMatrix();
2305 	Dict *resDict = tPat->getResDict();
2306 #endif
2307 
2308 	PDFRectangle box;
2309 	Gfx *gfx;
2310 	QString id;
2311 	PageItem *ite;
2312 	groupEntry gElements;
2313 	m_groupStack.push(gElements);
2314 	double width, height;
2315 	width = bbox[2] - bbox[0];
2316 	height = bbox[3] - bbox[1];
2317 	if (xStep != width || yStep != height)
2318 		return gFalse;
2319 	box.x1 = bbox[0];
2320 	box.y1 = bbox[1];
2321 	box.x2 = bbox[2];
2322 	box.y2 = bbox[3];
2323 
2324 	const double *ctm = state->getCTM();
2325 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
2326 	QTransform mm = QTransform(mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
2327 	QTransform mmx = mm * m_ctm;
2328 
2329 	gfx = new Gfx(pdfDoc, this, resDict, &box, nullptr);
2330 	inPattern++;
2331 	// Unset the clip path as it is unrelated to the pattern's coordinate space.
2332 	QPainterPath savedClip = m_currentClipPath;
2333 	m_currentClipPath = QPainterPath();
2334 #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(21, 3, 0)
2335 	gfx->display(tPat->getContentStream());
2336 #else
2337 	gfx->display(str);
2338 #endif
2339 	m_currentClipPath = savedClip;
2340 	inPattern--;
2341 	gElements = m_groupStack.pop();
2342 	m_doc->m_Selection->clear();
2343 //	double pwidth = 0;
2344 //	double pheight = 0;
2345 	if (gElements.Items.count() > 0)
2346 	{
2347 		for (int dre = 0; dre < gElements.Items.count(); ++dre)
2348 		{
2349 			m_doc->m_Selection->addItem(gElements.Items.at(dre), true);
2350 			m_Elements->removeAll(gElements.Items.at(dre));
2351 		}
2352 		m_doc->itemSelection_FlipV();
2353 		PageItem *ite;
2354 		if (m_doc->m_Selection->count() > 1)
2355 			ite = m_doc->groupObjectsSelection();
2356 		else
2357 			ite = m_doc->m_Selection->itemAt(0);
2358 		ite->setFillTransparency(1.0 - state->getFillOpacity());
2359 		ite->setFillBlendmode(getBlendMode(state));
2360 		m_doc->m_Selection->clear();
2361 		ScPattern pat = ScPattern();
2362 		pat.setDoc(m_doc);
2363 		m_doc->DoDrawing = true;
2364 		pat.pattern = ite->DrawObj_toImage(qMin(qMax(ite->width(), ite->height()), 500.0));
2365 		pat.xoffset = 0;
2366 		pat.yoffset = 0;
2367 		m_doc->DoDrawing = false;
2368 		pat.width = ite->width();
2369 		pat.height = ite->height();
2370 	//	pwidth = ite->width();
2371 	//	pheight = ite->height();
2372 		ite->gXpos = 0;
2373 		ite->gYpos = 0;
2374 		ite->setXYPos(ite->gXpos, ite->gYpos, true);
2375 		pat.items.append(ite);
2376 		m_doc->Items->removeAll(ite);
2377 		id = QString("Pattern_from_PDF_%1").arg(m_doc->docPatterns.count() + 1);
2378 		m_doc->addPattern(id, pat);
2379 	}
2380 	double xCoor = m_doc->currentPage()->xOffset();
2381 	double yCoor = m_doc->currentPage()->yOffset();
2382 	double xmin, ymin, xmax, ymax;
2383 	// get the clip region bbox
2384 	state->getClipBBox(&xmin, &ymin, &xmax, &ymax);
2385 	QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax));
2386 	crect = crect.normalized();
2387 	QString output = QString("M %1 %2").arg(0.0).arg(0.0);
2388 	output += QString("L %1 %2").arg(crect.width()).arg(0.0);
2389 	output += QString("L %1 %2").arg(crect.width()).arg(crect.height());
2390 	output += QString("L %1 %2").arg(0.0).arg(crect.height());
2391 	output += QString("L %1 %2").arg(0.0).arg(0.0);
2392 	output += QString("Z");
2393 	pathIsClosed = true;
2394 	Coords = output;
2395 	int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, m_currColorFill, CommonStrings::None);
2396 	ite = m_doc->Items->at(z);
2397 
2398 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
2399 	double angle = m_ctm.map(QLineF(0, 0, 1, 0)).angle();
2400 	ite->setRotation(-angle);
2401 	if (checkClip())
2402 	{
2403 		QPainterPath outline = m_currentClipPath;
2404 		outline.translate(xCoor - ite->xPos(), yCoor - ite->yPos());
2405 		// Undo the rotation of the clipping path as it is rotated together with the item.
2406 		QTransform mm;
2407 		mm.rotate(angle);
2408 		outline = mm.map(outline);
2409 		ite->PoLine.fromQPainterPath(outline, true);
2410 		ite->setFillEvenOdd(outline.fillRule() == Qt::OddEvenFill);
2411 	}
2412 	ite->ClipEdited = true;
2413 	ite->FrameType = 3;
2414 	ite->setFillShade(m_currFillShade);
2415 	ite->setLineShade(100);
2416 	ite->setFillTransparency(1.0 - state->getFillOpacity());
2417 	ite->setFillBlendmode(getBlendMode(state));
2418 	ite->setLineEnd(m_lineEnd);
2419 	ite->setLineJoin(m_lineJoin);
2420 	ite->setTextFlowMode(PageItem::TextFlowDisabled);
2421 	ite->GrType = 8;
2422 	ite->setPattern(id);
2423 	ite->setPatternTransform(fabs(pmat[0]) * 100, fabs(pmat[3]) * 100, mmx.dx() - ctm[4], mmx.dy() - ctm[5], 0, -1 * pmat[1], pmat[2]);
2424 	m_doc->adjustItemSize(ite);
2425 	m_Elements->append(ite);
2426 	if (m_groupStack.count() != 0)
2427 	{
2428 		m_groupStack.top().Items.append(ite);
2429 		applyMask(ite);
2430 	}
2431 	delete gfx;
2432 	return gTrue;
2433 }
2434 
2435 void SlaOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool interpolate, GBool inlineImg)
2436 {
2437 //	qDebug() << "Draw Image Mask";
2438 	QImage * image = nullptr;
2439 	int invert_bit;
2440 	int row_stride;
2441 	int x, y, i, bit;
2442 	unsigned char *dest = nullptr;
2443 	unsigned char *buffer;
2444 	Guchar *pix;
2445 	ImageStream * imgStr = new ImageStream(str, width, 1, 1);
2446 	imgStr->reset();
2447 #ifdef WORDS_BIGENDIAN
2448 	image = new QImage(width, height, QImage::Format_Mono);
2449 #else
2450 	image = new QImage(width, height, QImage::Format_MonoLSB);
2451 #endif
2452 	if (image == nullptr || image->isNull())
2453 	{
2454 		delete imgStr;
2455 		delete image;
2456 		return;
2457 	}
2458 	invert_bit = invert ? 1 : 0;
2459 	buffer = image->bits();
2460 	row_stride = image->bytesPerLine();
2461 	for (y = 0; y < height; y++)
2462 	{
2463 		pix = imgStr->getLine();
2464 		dest = buffer + y * row_stride;
2465 		i = 0;
2466 		bit = 0;
2467 		for (x = 0; x < width; x++)
2468 		{
2469 			if (bit == 0)
2470 				dest[i] = 0;
2471 			if (!(pix[x] ^ invert_bit))
2472 			{
2473 #ifdef WORDS_BIGENDIAN
2474 				dest[i] |= (1 << (7 - bit));
2475 #else
2476 				dest[i] |= (1 << bit);
2477 #endif
2478 			}
2479 			bit++;
2480 			if (bit > 7)
2481 			{
2482 				bit = 0;
2483 				i++;
2484 			}
2485 		}
2486 	}
2487 	QColor backColor = ScColorEngine::getShadeColorProof(m_doc->PageColors[m_currColorFill], m_doc, m_currFillShade);
2488 	QImage res = QImage(width, height, QImage::Format_ARGB32);
2489 	res.fill(backColor.rgb());
2490 	unsigned char cc, cm, cy, ck;
2491 	for (int yi = 0; yi < res.height(); ++yi)
2492 	{
2493 		QRgb *t = (QRgb*)(res.scanLine( yi ));
2494 		for (int xi = 0; xi < res.width(); ++xi)
2495 		{
2496 			cc = qRed(*t);
2497 			cm = qGreen(*t);
2498 			cy = qBlue(*t);
2499 			ck = image->pixel(xi, yi);
2500 			if (ck == 0)
2501 				(*t) = qRgba(cc, cm, cy, 0);
2502 			else
2503 				(*t) = qRgba(cc, cm, cy, 255);
2504 			t++;
2505 		}
2506 	}
2507 
2508 	createImageFrame(res, state, 3);
2509 
2510 	imgStr->close();
2511 	delete imgStr;
2512 	delete image;
2513 }
2514 
2515 void SlaOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool interpolate, Stream *maskStr, int maskWidth, int maskHeight,
2516 				   GfxImageColorMap *maskColorMap, GBool maskInterpolate)
2517 {
2518 //	qDebug() << "SlaOutputDev::drawSoftMaskedImage Masked Image Components" << colorMap->getNumPixelComps();
2519 	ImageStream * imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
2520 	imgStr->reset();
2521 	unsigned int *dest = nullptr;
2522 	unsigned char * buffer = new unsigned char[width * height * 4];
2523 	QImage * image = nullptr;
2524 	for (int y = 0; y < height; y++)
2525 	{
2526 		dest = (unsigned int *)(buffer + y * 4 * width);
2527 		Guchar * pix = imgStr->getLine();
2528 		colorMap->getRGBLine(pix, dest, width);
2529 	}
2530 	image = new QImage(buffer, width, height, QImage::Format_RGB32);
2531 	if (image == nullptr || image->isNull())
2532 	{
2533 		delete imgStr;
2534 		delete[] buffer;
2535 		delete image;
2536 		return;
2537 	}
2538 	ImageStream *mskStr = new ImageStream(maskStr, maskWidth, maskColorMap->getNumPixelComps(), maskColorMap->getBits());
2539 	mskStr->reset();
2540 	Guchar *mdest = nullptr;
2541 	unsigned char * mbuffer = new unsigned char[maskWidth * maskHeight];
2542 	memset(mbuffer, 0, maskWidth * maskHeight);
2543 	for (int y = 0; y < maskHeight; y++)
2544 	{
2545 		mdest = (Guchar *)(mbuffer + y * maskWidth);
2546 		Guchar * pix = mskStr->getLine();
2547 		maskColorMap->getGrayLine(pix, mdest, maskWidth);
2548 	}
2549 	if ((maskWidth != width) || (maskHeight != height))
2550 		*image = image->scaled(maskWidth, maskHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2551 	QImage res = image->convertToFormat(QImage::Format_ARGB32);
2552 
2553 	int matteRc, matteGc, matteBc;
2554 	POPPLER_CONST_070 GfxColor *matteColor = maskColorMap->getMatteColor();
2555 	if (matteColor != nullptr)
2556 	{
2557 		GfxRGB matteRgb;
2558 		colorMap->getColorSpace()->getRGB(matteColor, &matteRgb);
2559 		matteRc = qRound(colToDbl(matteRgb.r) * 255);
2560 		matteGc = qRound(colToDbl(matteRgb.g) * 255);
2561 		matteBc = qRound(colToDbl(matteRgb.b) * 255);
2562 	}
2563 
2564 	unsigned char cr, cg, cb, ca;
2565 	int s = 0;
2566 	for (int yi=0; yi < res.height(); ++yi)
2567 	{
2568 		QRgb *t = (QRgb*)(res.scanLine( yi ));
2569 		for (int xi=0; xi < res.width(); ++xi)
2570 		{
2571 			cr = qRed(*t);
2572 			cg = qGreen(*t);
2573 			cb = qBlue(*t);
2574 			ca = mbuffer[s];
2575 			if (matteColor != nullptr)
2576 			{
2577 				cr = unblendMatte(cr, ca, matteRc);
2578 				cg = unblendMatte(cg, ca, matteGc);
2579 				cb = unblendMatte(cb, ca, matteBc);
2580 			}
2581 			(*t) = qRgba(cr, cg, cb, ca);
2582 			s++;
2583 			t++;
2584 		}
2585 	}
2586 
2587 	createImageFrame(res, state, 3);
2588 
2589 	delete imgStr;
2590 	delete[] buffer;
2591 	delete image;
2592 	delete mskStr;
2593 	delete[] mbuffer;
2594 }
2595 
2596 void SlaOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,  int width, int height, GfxImageColorMap *colorMap, GBool interpolate, Stream *maskStr, int maskWidth, int maskHeight, GBool maskInvert, GBool maskInterpolate)
2597 {
2598 //	qDebug() << "SlaOutputDev::drawMaskedImage";
2599 	ImageStream * imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
2600 	imgStr->reset();
2601 	unsigned int *dest = nullptr;
2602 	unsigned char * buffer = new unsigned char[width * height * 4];
2603 	QImage * image = nullptr;
2604 	for (int y = 0; y < height; y++)
2605 	{
2606 		dest = (unsigned int *)(buffer + y * 4 * width);
2607 		Guchar * pix = imgStr->getLine();
2608 		colorMap->getRGBLine(pix, dest, width);
2609 	}
2610 	image = new QImage(buffer, width, height, QImage::Format_RGB32);
2611 	if (image == nullptr || image->isNull())
2612 	{
2613 		delete imgStr;
2614 		delete[] buffer;
2615 		delete image;
2616 		return;
2617 	}
2618 	ImageStream *mskStr = new ImageStream(maskStr, maskWidth, 1, 1);
2619 	mskStr->reset();
2620 	Guchar *mdest = nullptr;
2621 	int invert_bit = maskInvert ? 1 : 0;
2622 	unsigned char * mbuffer = new unsigned char[maskWidth * maskHeight];
2623 	memset(mbuffer, 0, maskWidth * maskHeight);
2624 	for (int y = 0; y < maskHeight; y++)
2625 	{
2626 		mdest = (Guchar *)(mbuffer + y * maskWidth);
2627 		Guchar * pix = mskStr->getLine();
2628 		for (int x = 0; x < maskWidth; x++)
2629 		{
2630 			if (pix[x] ^ invert_bit)
2631 				*mdest++ = 0;
2632 			else
2633 				*mdest++ = 255;
2634 		}
2635 	}
2636 	if ((maskWidth != width) || (maskHeight != height))
2637 		*image = image->scaled(maskWidth, maskHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
2638 	QImage res = image->convertToFormat(QImage::Format_ARGB32);
2639 	unsigned char cc, cm, cy, ck;
2640 	int s = 0;
2641 	for (int yi=0; yi < res.height(); ++yi)
2642 	{
2643 		QRgb *t = (QRgb*)(res.scanLine( yi ));
2644 		for (int xi=0; xi < res.width(); ++xi)
2645 		{
2646 			cc = qRed(*t);
2647 			cm = qGreen(*t);
2648 			cy = qBlue(*t);
2649 			ck = mbuffer[s];
2650 			(*t) = qRgba(cc, cm, cy, ck);
2651 			s++;
2652 			t++;
2653 		}
2654 	}
2655 
2656 	createImageFrame(res, state, colorMap->getNumPixelComps());
2657 
2658 	delete imgStr;
2659 	delete[] buffer;
2660 	delete image;
2661 	delete mskStr;
2662 	delete[] mbuffer;
2663 }
2664 
2665 void SlaOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool interpolate, POPPLER_CONST_082 int* maskColors, GBool inlineImg)
2666 {
2667 	ImageStream * imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
2668 //	qDebug() << "SlaOutputDev::drawImage Image Components" << colorMap->getNumPixelComps() << "Mask" << maskColors;
2669 	imgStr->reset();
2670 	QImage* image = nullptr;
2671 	if (maskColors)
2672 	{
2673 		image = new QImage(width, height, QImage::Format_ARGB32);
2674 		for (int y = 0; y < height; y++)
2675 		{
2676 			QRgb *s = (QRgb*)(image->scanLine(y));
2677 			Guchar *pix = imgStr->getLine();
2678 			for (int x = 0; x < width; x++)
2679 			{
2680 				GfxRGB rgb;
2681 				colorMap->getRGB(pix, &rgb);
2682 				int Rc = qRound(colToDbl(rgb.r) * 255);
2683 				int Gc = qRound(colToDbl(rgb.g) * 255);
2684 				int Bc = qRound(colToDbl(rgb.b) * 255);
2685 				*s = qRgba(Rc, Gc, Bc, 255);
2686 				for (int i = 0; i < colorMap->getNumPixelComps(); ++i)
2687 				{
2688 					if (pix[i] < maskColors[2*i] * 255 || pix[i] > maskColors[2*i+1] * 255)
2689 					{
2690 						*s = *s | 0xff000000;
2691 						break;
2692 					}
2693 				}
2694 				s++;
2695 				pix += colorMap->getNumPixelComps();
2696 			}
2697 		}
2698 	}
2699 	else
2700 	{
2701 		image = new QImage(width, height, QImage::Format_ARGB32);
2702 		for (int y = 0; y < height; y++)
2703 		{
2704 			QRgb *s = (QRgb*)(image->scanLine(y));
2705 			Guchar *pix = imgStr->getLine();
2706 			for (int x = 0; x < width; x++)
2707 			{
2708 				if (colorMap->getNumPixelComps() == 4)
2709 				{
2710 					GfxCMYK cmyk;
2711 					colorMap->getCMYK(pix, &cmyk);
2712 					int Cc = qRound(colToDbl(cmyk.c) * 255);
2713 					int Mc = qRound(colToDbl(cmyk.m) * 255);
2714 					int Yc = qRound(colToDbl(cmyk.y) * 255);
2715 					int Kc = qRound(colToDbl(cmyk.k) * 255);
2716 					*s = qRgba(Yc, Mc, Cc, Kc);
2717 				}
2718 				else
2719 				{
2720 					GfxRGB rgb;
2721 					colorMap->getRGB(pix, &rgb);
2722 					int Rc = qRound(colToDbl(rgb.r) * 255);
2723 					int Gc = qRound(colToDbl(rgb.g) * 255);
2724 					int Bc = qRound(colToDbl(rgb.b) * 255);
2725 					*s = qRgba(Rc, Gc, Bc, 255);
2726 				}
2727 				s++;
2728 				pix += colorMap->getNumPixelComps();
2729 			}
2730 		}
2731 	}
2732 
2733 	if (image != nullptr && !image->isNull()) {
2734 		createImageFrame(*image, state, colorMap->getNumPixelComps());
2735 	}
2736 
2737 	delete imgStr;
2738 	delete image;
2739 }
2740 
2741 void SlaOutputDev::createImageFrame(QImage& image, GfxState *state, int numColorComponents)
2742 {
2743 //	qDebug() << "SlaOutputDev::createImageFrame";
2744 	const double *ctm = state->getCTM();
2745 	double xCoor = m_doc->currentPage()->xOffset();
2746 	double yCoor = m_doc->currentPage()->yOffset();
2747 
2748 	m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
2749 	double angle = m_ctm.map(QLineF(0, 0, 1, 0)).angle();
2750 	QPointF torigin;
2751 	// In PDF all images considered squares with unit length that are transformed into the proper
2752 	// dimensions by ctm.
2753 	// A positive determinant retains orientation. Thus orientation is the same as in the PDF
2754 	// coordinate system (y-axis increases upwards). As Scribus uses the inverse orientation the
2755 	// image needs to be flipped (a horizontal flip is applied later).  For a flipped image the
2756 	// corner that will be origin in Scribus is the upper right corner (1, 1) of the image.
2757 	// A negative determinant changes the orientation such that the image is already in the Scribus
2758 	// coordinate orientation and no flip is necessary. The origin will be the upper left corner (0, 1).
2759 	if (m_ctm.determinant() > 0) {
2760 		torigin = m_ctm.map(QPointF(1, 1));
2761 	} else {
2762 		torigin = m_ctm.map(QPointF(0, 1));
2763 	}
2764 
2765 	// Determine the visible area of the picture after clipping it. If it is empty, no item
2766 	// needs to be created.
2767 	QPainterPath outline;
2768 	outline.addRect(0, 0, 1, 1);
2769 	outline = m_ctm.map(outline);
2770 	outline = intersection(outline, m_currentClipPath);
2771 
2772 	if ((inPattern == 0) && (outline.isEmpty() || outline.boundingRect().isNull()))
2773 		return;
2774 
2775     // Determine the width and height of the image by undoing the rotation part
2776 	// of the CTM and applying the result to the unit square.
2777 	QTransform without_rotation;
2778 	without_rotation = m_ctm * without_rotation.rotate(angle);
2779 	QRectF trect_wr = without_rotation.mapRect(QRectF(0, 0, 1, 1));
2780 
2781 	int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Rectangle, xCoor + torigin.x(), yCoor + torigin.y(), trect_wr.width(), trect_wr.height(), 0, CommonStrings::None, CommonStrings::None);
2782 	PageItem* ite = m_doc->Items->at(z);
2783 	ite->ClipEdited = true;
2784 	ite->FrameType = 3;
2785 	m_doc->setRedrawBounding(ite);
2786 	ite->Clip = flattenPath(ite->PoLine, ite->Segments);
2787 	ite->setTextFlowMode(PageItem::TextFlowDisabled);
2788 	ite->setFillShade(100);
2789 	ite->setLineShade(100);
2790 	ite->setFillEvenOdd(false);
2791 	ite->setFillTransparency(1.0 - state->getFillOpacity());
2792 	ite->setFillBlendmode(getBlendMode(state));
2793 	if (m_ctm.determinant() > 0)
2794 	{
2795 		ite->setRotation(-(angle - 180));
2796 		ite->setImageFlippedH(true);
2797 	}
2798 	else
2799 		ite->setRotation(-angle);
2800 	m_doc->adjustItemSize(ite);
2801 
2802 	if (numColorComponents == 4)
2803 	{
2804 		QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pdf_XXXXXX.tif");
2805 		tempFile->setAutoRemove(false);
2806 		if (tempFile->open())
2807 		{
2808 			QString fileName = getLongPathName(tempFile->fileName());
2809 			if (!fileName.isEmpty())
2810 			{
2811 				tempFile->close();
2812 				ite->isInlineImage = true;
2813 				ite->isTempFile = true;
2814 				ite->AspectRatio = false;
2815 				ite->ScaleType   = false;
2816 				TIFF* tif = TIFFOpen(fileName.toLocal8Bit().data(), "w");
2817 				if (tif)
2818 				{
2819 					TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, image.width());
2820 					TIFFSetField(tif, TIFFTAG_IMAGELENGTH, image.height());
2821 					TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
2822 					TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
2823 					TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
2824 					TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_SEPARATED);
2825 					TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
2826 					for (int y = 0; y < image.height(); ++y)
2827 					{
2828 						TIFFWriteScanline(tif, image.scanLine(y), y);
2829 					}
2830 					TIFFClose(tif);
2831 					m_doc->loadPict(fileName, ite);
2832 				}
2833 				m_Elements->append(ite);
2834 				if (m_groupStack.count() != 0)
2835 				{
2836 					m_groupStack.top().Items.append(ite);
2837 					applyMask(ite);
2838 				}
2839 			}
2840 			else
2841 				m_doc->Items->removeAll(ite);
2842 		}
2843 		delete tempFile;
2844 	}
2845 	else
2846 	{
2847 		QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pdf_XXXXXX.png");
2848 		tempFile->setAutoRemove(false);
2849 		if (tempFile->open())
2850 		{
2851 			QString fileName = getLongPathName(tempFile->fileName());
2852 			if (!fileName.isEmpty())
2853 			{
2854 				tempFile->close();
2855 				ite->isInlineImage = true;
2856 				ite->isTempFile = true;
2857 				ite->AspectRatio = false;
2858 				ite->ScaleType   = false;
2859 				image.save(fileName, "PNG");
2860 				m_doc->loadPict(fileName, ite);
2861 				m_Elements->append(ite);
2862 				if (m_groupStack.count() != 0)
2863 				{
2864 					m_groupStack.top().Items.append(ite);
2865 					applyMask(ite);
2866 				}
2867 			}
2868 			else
2869 				m_doc->Items->removeAll(ite);
2870 		}
2871 		delete tempFile;
2872 	}
2873 	if (inPattern == 0)
2874 	{
2875 		outline.translate(xCoor - ite->xPos(), yCoor - ite->yPos());
2876 		// Undo the rotation of the clipping path as it is rotated together with the iamge.
2877 		QTransform mm;
2878 		mm.rotate(-ite->rotation());
2879 		outline = mm.map(outline);
2880 		ite->PoLine.fromQPainterPath(outline, true);
2881 		ite->setFillEvenOdd(outline.fillRule() == Qt::OddEvenFill);
2882 		ite->ClipEdited = true;
2883 		ite->FrameType = 3;
2884 		ite->setTextFlowMode(PageItem::TextFlowDisabled);
2885 		ite->ScaleType   = true;
2886 		m_doc->adjustItemSize(ite);
2887 		ite->OldB2 = ite->width();
2888 		ite->OldH2 = ite->height();
2889 		ite->updateClip();
2890 	}
2891 }
2892 
2893 void SlaOutputDev::beginMarkedContent(POPPLER_CONST char *name, Object *dictRef)
2894 {
2895 	mContent mSte;
2896 	mSte.name = QString(name);
2897 	mSte.ocgName = "";
2898 	if (importerFlags & LoadSavePlugin::lfCreateDoc)
2899 	{
2900 		if (dictRef->isNull())
2901 			return;
2902 		Object dictObj;
2903 		Dict *dict;
2904 		Object dictType;
2905 		OCGs *contentConfig = catalog->getOptContentConfig();
2906 		OptionalContentGroup *oc;
2907 		if (dictRef->isRef())
2908 		{
2909 			oc = contentConfig->findOcgByRef(dictRef->getRef());
2910 			if (oc)
2911 			{
2912 //				qDebug() << "Begin OCG Content (Ref) with Name " << QString(name) << "Layer" << UnicodeParsedString(oc->getName());
2913 				m_doc->setActiveLayer(UnicodeParsedString(oc->getName()));
2914 				mSte.ocgName = UnicodeParsedString(oc->getName());
2915 			}
2916 		}
2917 		else
2918 		{
2919 			dictObj = dictRef->fetch(xref);
2920 			if (!dictObj.isDict())
2921 				return;
2922 			dict = dictObj.getDict();
2923 			dictType = dict->lookup("Type");
2924 			if (dictType.isName("OCG"))
2925 			{
2926 				oc = contentConfig->findOcgByRef(dictRef->getRef());
2927 				if (oc)
2928 				{
2929 					//					qDebug() << "Begin OCG Content with Name " << UnicodeParsedString(oc->getName());
2930 					m_doc->setActiveLayer(UnicodeParsedString(oc->getName()));
2931 					mSte.ocgName = UnicodeParsedString(oc->getName());
2932 				}
2933 			}
2934 		}
2935 	}
2936 	m_mcStack.push(mSte);
2937 }
2938 
2939 void SlaOutputDev::beginMarkedContent(POPPLER_CONST char *name, Dict *properties)
2940 {
2941 //	qDebug() << "Begin Marked Content with Name " << QString(name);
2942 	QString nam = QString(name);
2943 	mContent mSte;
2944 	mSte.name = nam;
2945 	mSte.ocgName = "";
2946 	m_mcStack.push(mSte);
2947 	if (importerFlags & LoadSavePlugin::lfCreateDoc)
2948 	{
2949 		if (nam == "Layer")		// Handle Adobe Illustrator Layer command
2950 		{
2951 			if (layersSetByOCG)
2952 				return;
2953 			QString lName = QString("Layer_%1").arg(layerNum + 1);
2954 			Object obj = properties->lookup((char*) "Title");
2955 			if (obj.isString())
2956 				lName = QString(obj.getString()->getCString());
2957 			for (ScLayers::iterator it = m_doc->Layers.begin(); it != m_doc->Layers.end(); ++it)
2958 			{
2959 				if (it->Name == lName)
2960 				{
2961 					m_doc->setActiveLayer(lName);
2962 					return;
2963 				}
2964 			}
2965 			layerNum++;
2966 			if (!firstLayer)
2967 				currentLayer = m_doc->addLayer(lName, true);
2968 			firstLayer = false;
2969 
2970 			obj = properties->lookup((char*) "Visible");
2971 			if (obj.isBool())
2972 				m_doc->setLayerVisible(currentLayer, obj.getBool());
2973 			obj = properties->lookup((char*) "Editable");
2974 			if (obj.isBool())
2975 				m_doc->setLayerLocked(currentLayer, !obj.getBool());
2976 			obj = properties->lookup((char*) "Printed");
2977 			if (obj.isBool())
2978 				m_doc->setLayerPrintable(currentLayer, obj.getBool());
2979 			obj = properties->lookup((char*)"Color");
2980 			if (obj.isArray())
2981 			{
2982 				Object obj1;
2983 				obj1 = obj.arrayGet(0);
2984 				int r = obj1.getNum() / 256;
2985 				obj1 = obj.arrayGet(1);
2986 				int g = obj1.getNum() / 256;
2987 				obj1 = obj.arrayGet(2);
2988 				int b = obj1.getNum() / 256;
2989 				m_doc->setLayerMarker(currentLayer, QColor(r, g, b));
2990 			}
2991 		}
2992 	}
2993 }
2994 
2995 void SlaOutputDev::endMarkedContent(GfxState *state)
2996 {
2997 //	qDebug() << "End Marked Content";
2998 	if (m_mcStack.count() > 0)
2999 	{
3000 		mContent mSte = m_mcStack.pop();
3001 		if (importerFlags & LoadSavePlugin::lfCreateDoc)
3002 		{
3003 			if (mSte.name == "OC")
3004 			{
3005 				for (ScLayers::iterator it = m_doc->Layers.begin(); it != m_doc->Layers.end(); ++it)
3006 				{
3007 					if (it->Name == mSte.ocgName)
3008 					{
3009 						m_doc->setActiveLayer(mSte.ocgName);
3010 						return;
3011 					}
3012 				}
3013 			}
3014 		}
3015 	}
3016 }
3017 
3018 void SlaOutputDev::markPoint(POPPLER_CONST char *name)
3019 {
3020 //	qDebug() << "Begin Marked Point with Name " << QString(name);
3021 }
3022 
3023 void SlaOutputDev::markPoint(POPPLER_CONST char *name, Dict *properties)
3024 {
3025 //	qDebug() << "Begin Marked Point with Name " << QString(name) << "and Properties";
3026 	beginMarkedContent(name, properties);
3027 }
3028 
3029 void SlaOutputDev::updateFont(GfxState *state)
3030 {
3031 	GfxFont *gfxFont;
3032 	GfxFontLoc *fontLoc;
3033 	GfxFontType fontType;
3034 	SlaOutFontFileID *id;
3035 	SplashFontFile *fontFile;
3036 	SplashFontSrc *fontsrc = nullptr;
3037 	FoFiTrueType *ff;
3038 	Object refObj, strObj;
3039 	GooString *fileName;
3040 	char *tmpBuf;
3041 	int tmpBufLen = 0;
3042 	int *codeToGID;
3043 	const double *textMat;
3044 	double m11, m12, m21, m22, fontSize;
3045 	SplashCoord mat[4];
3046 	int n = 0;
3047 	int faceIndex = 0;
3048 	SplashCoord matrix[6];
3049 
3050 	m_font = nullptr;
3051 	fileName = nullptr;
3052 	tmpBuf = nullptr;
3053 	fontLoc = nullptr;
3054 
3055 	gfxFont = state->getFont();
3056 	if (!gfxFont)
3057 		goto err1;
3058 
3059 	fontType = gfxFont->getType();
3060 	if (fontType == fontType3)
3061 		goto err1;
3062 
3063 	// check the font file cache
3064 	id = new SlaOutFontFileID(gfxFont->getID());
3065 	if ((fontFile = m_fontEngine->getFontFile(id)))
3066 		delete id;
3067 	else
3068 	{
3069 		if (!(fontLoc = gfxFont->locateFont(xref, nullptr)))
3070 		{
3071 			error(errSyntaxError, -1, "Couldn't find a font for '{0:s}'",
3072 			gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)");
3073 			goto err2;
3074 		}
3075 
3076 		// embedded font
3077 		if (fontLoc->locType == gfxFontLocEmbedded)
3078 		{
3079 			// if there is an embedded font, read it to memory
3080 			tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen);
3081 			if (! tmpBuf)
3082 				goto err2;
3083 
3084 			// external font
3085 		}
3086 		else
3087 		{ // gfxFontLocExternal
3088 			fileName = fontLoc->path;
3089 			fontType = fontLoc->fontType;
3090 		}
3091 
3092 		fontsrc = new SplashFontSrc;
3093 		if (fileName)
3094 			fontsrc->setFile(fileName, gFalse);
3095 		else
3096 			fontsrc->setBuf(tmpBuf, tmpBufLen, gTrue);
3097 
3098 		// load the font file
3099 		switch (fontType) {
3100 		case fontType1:
3101 			if (!(fontFile = m_fontEngine->loadType1Font(
3102 				id,
3103 				fontsrc,
3104 				(const char **)((Gfx8BitFont *) gfxFont)->getEncoding())))
3105 			{
3106 				error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
3107 				gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)");
3108 				goto err2;
3109 			}
3110 			break;
3111 		case fontType1C:
3112 			if (!(fontFile = m_fontEngine->loadType1CFont(
3113 							id,
3114 							fontsrc,
3115 							(const char **)((Gfx8BitFont *) gfxFont)->getEncoding())))
3116 			{
3117 				error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
3118 				gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)");
3119 				goto err2;
3120 			}
3121 			break;
3122 		case fontType1COT:
3123 			if (!(fontFile = m_fontEngine->loadOpenTypeT1CFont(
3124 							id,
3125 							fontsrc,
3126 							(const char **)((Gfx8BitFont *) gfxFont)->getEncoding())))
3127 			{
3128 				error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
3129 				gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)");
3130 				goto err2;
3131 			}
3132 			break;
3133 		case fontTrueType:
3134 		case fontTrueTypeOT:
3135 			if (fileName)
3136 				ff = FoFiTrueType::load(fileName->getCString());
3137 			else
3138 				ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
3139 			if (ff)
3140 			{
3141 				codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff);
3142 				n = 256;
3143 				delete ff;
3144 			}
3145 			else
3146 			{
3147 				codeToGID = nullptr;
3148 				n = 0;
3149 			}
3150 			if (!(fontFile = m_fontEngine->loadTrueTypeFont(
3151 							id,
3152 							fontsrc,
3153 							codeToGID, n)))
3154 			{
3155 				error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
3156 				gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)");
3157 				goto err2;
3158 			}
3159 			break;
3160 		case fontCIDType0:
3161 		case fontCIDType0C:
3162 			if (!(fontFile = m_fontEngine->loadCIDFont(
3163 							id,
3164 							fontsrc)))
3165 			{
3166 				error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
3167 				gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)");
3168 				goto err2;
3169 			}
3170 			break;
3171 		case fontCIDType0COT:
3172 			if (((GfxCIDFont *) gfxFont)->getCIDToGID())
3173 			{
3174 				n = ((GfxCIDFont *) gfxFont)->getCIDToGIDLen();
3175 				codeToGID = (int *) gmallocn(n, sizeof(*codeToGID));
3176 				memcpy(codeToGID, ((GfxCIDFont *) gfxFont)->getCIDToGID(), n * sizeof(*codeToGID));
3177 			}
3178 			else
3179 			{
3180 				codeToGID = nullptr;
3181 				n = 0;
3182 			}
3183 			if (!(fontFile = m_fontEngine->loadOpenTypeCFFFont(
3184 							id,
3185 							fontsrc,
3186 							codeToGID, n)))
3187 			{
3188 				error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
3189 				gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)");
3190 				goto err2;
3191 			}
3192 			break;
3193 		case fontCIDType2:
3194 		case fontCIDType2OT:
3195 			codeToGID = nullptr;
3196 			n = 0;
3197 			if (((GfxCIDFont *) gfxFont)->getCIDToGID())
3198 			{
3199 				n = ((GfxCIDFont *) gfxFont)->getCIDToGIDLen();
3200 				if (n)
3201 				{
3202 					codeToGID = (int *)gmallocn(n, sizeof(*codeToGID));
3203 					memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), n * sizeof(*codeToGID));
3204 				}
3205 			}
3206 			else
3207 			{
3208 				if (fileName)
3209 					ff = FoFiTrueType::load(fileName->getCString());
3210 				else
3211 					ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
3212 				if (! ff)
3213 					goto err2;
3214 				codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n);
3215 				delete ff;
3216 			}
3217 			if (!(fontFile = m_fontEngine->loadTrueTypeFont(
3218 							id,
3219 							fontsrc,
3220 							codeToGID, n, faceIndex)))
3221 			{
3222 				error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
3223 				gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)");
3224 				goto err2;
3225 			}
3226 			break;
3227 		default:
3228 			// this shouldn't happen
3229 			goto err2;
3230 		}
3231 	}
3232 	// get the font matrix
3233 	textMat = state->getTextMat();
3234 	fontSize = state->getFontSize();
3235 	m11 = textMat[0] * fontSize * state->getHorizScaling();
3236 	m12 = textMat[1] * fontSize * state->getHorizScaling();
3237 	m21 = textMat[2] * fontSize;
3238 	m22 = textMat[3] * fontSize;
3239 	matrix[0] = 1;
3240 	matrix[1] = 0;
3241 	matrix[2] = 0;
3242 	matrix[3] = 1;
3243 	matrix[4] = 0;
3244 	matrix[5] = 0;
3245 	// create the scaled font
3246 	mat[0] = m11;
3247 	mat[1] = -m12;
3248 	mat[2] = m21;
3249 	mat[3] = -m22;
3250 	m_font = m_fontEngine->getFont(fontFile, mat, matrix);
3251 
3252 	delete fontLoc;
3253 	if (fontsrc && !fontsrc->isFile)
3254 		fontsrc->unref();
3255 	return;
3256 
3257 err2:
3258 	delete id;
3259 	delete fontLoc;
3260 err1:
3261 	if (fontsrc && !fontsrc->isFile)
3262 		fontsrc->unref();
3263 }
3264 
3265 void SlaOutputDev::drawChar(GfxState* state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, POPPLER_CONST_082 Unicode* u, int uLen)
3266 {
3267 //	qDebug() << "SlaOutputDev::drawChar code:" << code << "bytes:" << nBytes << "Unicode:" << u << "ulen:" << uLen << "render:" << state->getRender();
3268 	double x1, y1, x2, y2;
3269 	updateFont(state);
3270 	if (!m_font)
3271 		return;
3272 
3273 	// PDF 1.7 Section 9.3.6 defines eight text rendering modes.
3274 	// 0 - Fill
3275 	// 1 - Stroke
3276 	// 2 - First fill and then stroke
3277 	// 3 - Invisible
3278 	// 4 - Fill and use as a clipping path
3279 	// 5 - Stroke and use as a clipping path
3280 	// 6 - First fill, then stroke and add as a clipping path
3281 	// 7 - Only use as a clipping path.
3282 	// TODO Implement the clipping operations. At least the characters are shown.
3283 	int textRenderingMode = state->getRender();
3284 	// Invisible or only used for clipping
3285 	if (textRenderingMode == 3)
3286 		return;
3287 	if (textRenderingMode < 8)
3288 	{
3289 		SplashPath * fontPath;
3290 		fontPath = m_font->getGlyphPath(code);
3291 		if (fontPath)
3292 		{
3293 			QPainterPath qPath;
3294 			qPath.setFillRule(Qt::WindingFill);
3295 			for (int i = 0; i < fontPath->getLength(); ++i)
3296 			{
3297 				Guchar f;
3298 				fontPath->getPoint(i, &x1, &y1, &f);
3299 				if (f & splashPathFirst)
3300 					qPath.moveTo(x1,y1);
3301 				else if (f & splashPathCurve)
3302 				{
3303 					double x3, y3;
3304 					++i;
3305 					fontPath->getPoint(i, &x2, &y2, &f);
3306 					++i;
3307 					fontPath->getPoint(i, &x3, &y3, &f);
3308 					qPath.cubicTo(x1,y1,x2,y2,x3,y3);
3309 				}
3310 				else
3311 					qPath.lineTo(x1, y1);
3312 				if (f & splashPathLast)
3313 					qPath.closeSubpath();
3314 			}
3315 			const double * ctm = state->getCTM();
3316 			m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]);
3317 			double xCoor = m_doc->currentPage()->xOffset();
3318 			double yCoor = m_doc->currentPage()->yOffset();
3319 			FPointArray textPath;
3320 			textPath.fromQPainterPath(qPath);
3321 			FPoint wh = textPath.widthHeight();
3322 			if (textRenderingMode > 3)
3323 			{
3324 				QTransform mm;
3325 				mm.scale(1, -1);
3326 				mm.translate(x, -y);
3327 				// Remember the glyph for later clipping
3328  				m_clipTextPath.addPath(m_ctm.map(mm.map(qPath)));
3329 			}
3330 			if ((textPath.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0)) && (textRenderingMode != 7))
3331 			{
3332 				int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CommonStrings::None, CommonStrings::None);
3333 				PageItem* ite = m_doc->Items->at(z);
3334 
3335 				// todo: merge this between vector and text implementations.
3336 				QTransform mm;
3337 				mm.scale(1, -1);
3338 				mm.translate(x, -y);
3339 				textPath.map(mm);
3340 				textPath.map(m_ctm);
3341 				ite->PoLine = textPath.copy();
3342 				setItemFillAndStroke(state, ite);
3343 				// Fill text rendering modes. See above
3344 				m_doc->adjustItemSize(ite);
3345 				m_Elements->append(ite);
3346 				if (m_groupStack.count() != 0)
3347 				{
3348 					m_groupStack.top().Items.append(ite);
3349 					applyMask(ite);
3350 				}
3351 			}
3352 			delete fontPath;
3353 
3354 		}
3355 	}
3356 }
3357 
3358 
3359 GBool SlaOutputDev::beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, POPPLER_CONST_082 Unicode *u, int uLen)
3360 {
3361 //	qDebug() << "beginType3Char";
3362 	GfxFont *gfxFont;
3363 	if (!(gfxFont = state->getFont()))
3364 		return gTrue;
3365 	if (gfxFont->getType() != fontType3)
3366 		return gTrue;
3367 	F3Entry f3e;
3368 	f3e.colored = false;
3369 	m_F3Stack.push(f3e);
3370 	pushGroup();
3371 	return gFalse;
3372 }
3373 
3374 void SlaOutputDev::endType3Char(GfxState *state)
3375 {
3376 //	qDebug() << "endType3Char";
3377 	F3Entry f3e = m_F3Stack.pop();
3378 	groupEntry gElements = m_groupStack.pop();
3379 	m_doc->m_Selection->clear();
3380 	if (gElements.Items.count() > 0)
3381 	{
3382 		m_doc->m_Selection->delaySignalsOn();
3383 		for (int dre = 0; dre < gElements.Items.count(); ++dre)
3384 		{
3385 			m_doc->m_Selection->addItem(gElements.Items.at(dre), true);
3386 			m_Elements->removeAll(gElements.Items.at(dre));
3387 		}
3388 		PageItem *ite;
3389 		if (m_doc->m_Selection->count() > 1)
3390 			ite = m_doc->groupObjectsSelection();
3391 		else
3392 			ite = m_doc->m_Selection->itemAt(0);
3393 		if (!f3e.colored)
3394 		{
3395 			m_doc->itemSelection_SetItemBrush(m_currColorFill);
3396 			m_doc->itemSelection_SetItemBrushShade(m_currFillShade);
3397 			m_doc->itemSelection_SetItemFillTransparency(1.0 - state->getFillOpacity());
3398 			m_doc->itemSelection_SetItemFillBlend(getBlendMode(state));
3399 		}
3400 		m_Elements->append(ite);
3401 		m_doc->m_Selection->clear();
3402 		m_doc->m_Selection->delaySignalsOff();
3403 	}
3404 }
3405 
3406 void SlaOutputDev::type3D0(GfxState * /*state*/, double /*wx*/, double /*wy*/)
3407 {
3408 //	qDebug() << "type3D0";
3409 	if (m_F3Stack.count() > 0)
3410 		m_F3Stack.top().colored = true;
3411 }
3412 
3413 void SlaOutputDev::type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury)
3414 {
3415 //	qDebug() << "type3D1";
3416 	if (m_F3Stack.count() > 0)
3417 		m_F3Stack.top().colored = false;
3418 }
3419 
3420 void SlaOutputDev::beginTextObject(GfxState *state)
3421 {
3422 	pushGroup();
3423 }
3424 
3425 void SlaOutputDev::endTextObject(GfxState *state)
3426 {
3427 //	qDebug() << "SlaOutputDev::endTextObject";
3428 	if (!m_clipTextPath.isEmpty())
3429 	{
3430 		m_currentClipPath = intersection(m_currentClipPath, m_clipTextPath);
3431 		m_clipTextPath = QPainterPath();
3432 	}
3433 	if (m_groupStack.count() != 0)
3434 	{
3435 		groupEntry gElements = m_groupStack.pop();
3436 		tmpSel->clear();
3437 		if (gElements.Items.count() > 0)
3438 		{
3439 			for (int dre = 0; dre < gElements.Items.count(); ++dre)
3440 			{
3441 				tmpSel->addItem(gElements.Items.at(dre), true);
3442 				m_Elements->removeAll(gElements.Items.at(dre));
3443 			}
3444 			PageItem *ite;
3445 			if (gElements.Items.count() != 1)
3446 				ite = m_doc->groupObjectsSelection(tmpSel);
3447 			else
3448 				ite = gElements.Items.first();
3449 			ite->setGroupClipping(false);
3450 			ite->setFillTransparency(1.0 - state->getFillOpacity());
3451 			ite->setFillBlendmode(getBlendMode(state));
3452 			for (int as = 0; as < tmpSel->count(); ++as)
3453 			{
3454 				m_Elements->append(tmpSel->itemAt(as));
3455 			}
3456 			if (m_groupStack.count() != 0)
3457 				applyMask(ite);
3458 		}
3459 		if (m_groupStack.count() != 0)
3460 		{
3461 			for (int as = 0; as < tmpSel->count(); ++as)
3462 			{
3463 				m_groupStack.top().Items.append(tmpSel->itemAt(as));
3464 			}
3465 		}
3466 		tmpSel->clear();
3467 	}
3468 }
3469 
3470 QString SlaOutputDev::getColor(GfxColorSpace *color_space, POPPLER_CONST_070 GfxColor *color, int *shade)
3471 {
3472 	QString fNam;
3473 	QString namPrefix = "FromPDF";
3474 	ScColor tmp;
3475 	tmp.setSpotColor(false);
3476 	tmp.setRegistrationColor(false);
3477 	*shade = 100;
3478 	/*if (m_F3Stack.count() > 0)
3479 	{
3480 		if (!m_F3Stack.top().colored)
3481 			return "Black";
3482 	}*/
3483 
3484 	if ((color_space->getMode() == csDeviceRGB) || (color_space->getMode() == csCalRGB))
3485 	{
3486 		GfxRGB rgb;
3487 		color_space->getRGB(color, &rgb);
3488 		double Rc = colToDbl(rgb.r);
3489 		double Gc = colToDbl(rgb.g);
3490 		double Bc = colToDbl(rgb.b);
3491 		tmp.setRgbColorF(Rc, Gc, Bc);
3492 		fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
3493 	}
3494 	else if (color_space->getMode() == csDeviceCMYK)
3495 	{
3496 		GfxCMYK cmyk;
3497 		color_space->getCMYK(color, &cmyk);
3498 		double Cc = colToDbl(cmyk.c);
3499 		double Mc = colToDbl(cmyk.m);
3500 		double Yc = colToDbl(cmyk.y);
3501 		double Kc = colToDbl(cmyk.k);
3502 		tmp.setCmykColorF(Cc, Mc, Yc, Kc);
3503 		fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
3504 	}
3505 	else if ((color_space->getMode() == csCalGray) || (color_space->getMode() == csDeviceGray))
3506 	{
3507 		GfxGray gray;
3508 		color_space->getGray(color, &gray);
3509 		double Kc = 1.0 - colToDbl(gray);
3510 		tmp.setCmykColorF(0, 0, 0, Kc);
3511 		fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
3512 	}
3513 	else if (color_space->getMode() == csSeparation)
3514 	{
3515 		GfxSeparationColorSpace* sepColorSpace = (GfxSeparationColorSpace*) color_space;
3516 		GfxColorSpace* altColorSpace = sepColorSpace->getAlt();
3517 		QString name = QString(sepColorSpace->getName()->getCString());
3518 		bool isRegistrationColor = (name == "All");
3519 		if (isRegistrationColor)
3520 		{
3521 			tmp.setCmykColorF(1.0, 1.0, 1.0, 1.0);
3522 			tmp.setRegistrationColor(true);
3523 			name = "Registration";
3524 		}
3525 		else if ((altColorSpace->getMode() == csDeviceRGB) || (altColorSpace->getMode() == csCalRGB))
3526 		{
3527 			double x = 1.0;
3528 			double comps[gfxColorMaxComps];
3529 			sepColorSpace->getFunc()->transform(&x, comps);
3530 			tmp.setRgbColorF(comps[0], comps[1], comps[2]);
3531 		}
3532 		else if ((altColorSpace->getMode() == csCalGray) || (altColorSpace->getMode() == csDeviceGray))
3533 		{
3534 			double x = 1.0;
3535 			double comps[gfxColorMaxComps];
3536 			sepColorSpace->getFunc()->transform(&x, comps);
3537 			tmp.setCmykColorF(0.0, 0.0, 0.0, 1.0 - comps[0]);
3538 		}
3539 		else if (altColorSpace->getMode() == csLab)
3540 		{
3541 			double x = 1.0;
3542 			double comps[gfxColorMaxComps];
3543 			sepColorSpace->getFunc()->transform(&x, comps);
3544 			tmp.setLabColor(comps[0], comps[1], comps[2]);
3545 		}
3546 		else
3547 		{
3548 			GfxCMYK cmyk;
3549 			color_space->getCMYK(color, &cmyk);
3550 			double Cc = colToDbl(cmyk.c);
3551 			double Mc = colToDbl(cmyk.m);
3552 			double Yc = colToDbl(cmyk.y);
3553 			double Kc = colToDbl(cmyk.k);
3554 			tmp.setCmykColorF(Cc, Mc, Yc, Kc);
3555 		}
3556 		tmp.setSpotColor(true);
3557 
3558 		fNam = m_doc->PageColors.tryAddColor(name, tmp);
3559 		*shade = qRound(colToDbl(color->c[0]) * 100);
3560 	}
3561 	else
3562 	{
3563 		GfxRGB rgb;
3564 		color_space->getRGB(color, &rgb);
3565 		double Rc = colToDbl(rgb.r);
3566 		double Gc = colToDbl(rgb.g);
3567 		double Bc = colToDbl(rgb.b);
3568 		tmp.setRgbColorF(Rc, Gc, Bc);
3569 		fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
3570 //		qDebug() << "update fill color other colorspace" << color_space->getMode() << "treating as rgb" << Rc << Gc << Bc;
3571 	}
3572 	if (fNam == namPrefix+tmp.name())
3573 		m_importedColors->append(fNam);
3574 	return fNam;
3575 }
3576 
3577 QString SlaOutputDev::getAnnotationColor(const AnnotColor *color)
3578 {
3579 	QString fNam;
3580 	QString namPrefix = "FromPDF";
3581 	ScColor tmp;
3582 	tmp.setSpotColor(false);
3583 	tmp.setRegistrationColor(false);
3584 	if (color->getSpace() == AnnotColor::colorTransparent)
3585 		return CommonStrings::None;
3586 	if (color->getSpace() == AnnotColor::colorRGB)
3587 	{
3588 		const double *color_data = color->getValues();
3589 		double Rc = color_data[0];
3590 		double Gc = color_data[1];
3591 		double Bc = color_data[2];
3592 		tmp.setRgbColorF(Rc, Gc, Bc);
3593 		fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
3594 	}
3595 	else if (color->getSpace() == AnnotColor::colorCMYK)
3596 	{
3597 		const double *color_data = color->getValues();
3598 		double Cc = color_data[0];
3599 		double Mc = color_data[1];
3600 		double Yc = color_data[2];
3601 		double Kc = color_data[3];
3602 		tmp.setCmykColorF(Cc, Mc, Yc, Kc);
3603 		fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
3604 	}
3605 	else if (color->getSpace() == AnnotColor::colorGray)
3606 	{
3607 		const double *color_data = color->getValues();
3608 		double Kc = 1.0 - color_data[0];
3609 		tmp.setCmykColorF(0, 0, 0, Kc);
3610 		fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp);
3611 	}
3612 	if (fNam == namPrefix+tmp.name())
3613 		m_importedColors->append(fNam);
3614 	return fNam;
3615 }
3616 
3617 QString SlaOutputDev::convertPath(POPPLER_CONST_083 GfxPath *path)
3618 {
3619 //	qDebug() << "SlaOutputDev::convertPath";
3620 	if (! path)
3621 		return QString();
3622 
3623 	QString output;
3624 	pathIsClosed = false;
3625 
3626 	for (int i = 0; i < path->getNumSubpaths(); ++i)
3627 	{
3628 		POPPLER_CONST_083 GfxSubpath * subpath = path->getSubpath(i);
3629 		if (subpath->getNumPoints() > 0)
3630 		{
3631 			output += QString("M %1 %2").arg(subpath->getX(0)).arg(subpath->getY(0));
3632 			int j = 1;
3633 			while (j < subpath->getNumPoints())
3634 			{
3635 				if (subpath->getCurve(j))
3636 				{
3637 					output += QString("C %1 %2 %3 %4 %5 %6")
3638 					.arg(subpath->getX(j)).arg(subpath->getY(j))
3639 					.arg(subpath->getX(j + 1)).arg(subpath->getY(j + 1))
3640 					.arg(subpath->getX(j + 2)).arg(subpath->getY(j + 2));
3641 					j += 3;
3642 				}
3643 				else
3644 				{
3645 					output += QString("L %1 %2").arg(subpath->getX(j)).arg(subpath->getY(j));
3646 					++j;
3647 				}
3648 			}
3649 			if (subpath->isClosed())
3650 			{
3651 				output += QString("Z");
3652 				pathIsClosed = true;
3653 			}
3654 		}
3655 	}
3656 	return output;
3657 }
3658 
3659 void SlaOutputDev::getPenState(GfxState *state)
3660 {
3661 	switch (state->getLineCap())
3662 	{
3663 		case 0:
3664 			m_lineEnd = Qt::FlatCap;
3665 			break;
3666 		case 1:
3667 			m_lineEnd = Qt::RoundCap;
3668 			break;
3669 		case 2:
3670 			m_lineEnd = Qt::SquareCap;
3671 			break;
3672 	}
3673 	switch (state->getLineJoin())
3674 	{
3675 		case 0:
3676 			m_lineJoin = Qt::MiterJoin;
3677 			break;
3678 		case 1:
3679 			m_lineJoin = Qt::RoundJoin;
3680 			break;
3681 		case 2:
3682 			m_lineJoin = Qt::BevelJoin;
3683 			break;
3684 	}
3685 	double lw = state->getLineWidth();
3686 	double *dashPattern;
3687 	int dashLength;
3688 	state->getLineDash(&dashPattern, &dashLength, &DashOffset);
3689 	QVector<double> pattern(dashLength);
3690 	for (int i = 0; i < dashLength; ++i)
3691 	{
3692 		pattern[i] = dashPattern[i] / lw;
3693 	}
3694 	DashValues = pattern;
3695 }
3696 
3697 int SlaOutputDev::getBlendMode(GfxState *state)
3698 {
3699 	int mode = 0;
3700 	switch (state->getBlendMode())
3701 	{
3702 		default:
3703 		case gfxBlendNormal:
3704 			mode = 0;
3705 			break;
3706 		case gfxBlendDarken:
3707 			mode = 1;
3708 			break;
3709 		case gfxBlendLighten:
3710 			mode = 2;
3711 			break;
3712 		case gfxBlendMultiply:
3713 			mode = 3;
3714 			break;
3715 		case gfxBlendScreen:
3716 			mode = 4;
3717 			break;
3718 		case gfxBlendOverlay:
3719 			mode = 5;
3720 			break;
3721 		case gfxBlendHardLight:
3722 			mode = 6;
3723 			break;
3724 		case gfxBlendSoftLight:
3725 			mode = 7;
3726 			break;
3727 		case gfxBlendDifference:
3728 			mode = 8;
3729 			break;
3730 		case gfxBlendExclusion:
3731 			mode = 9;
3732 			break;
3733 		case gfxBlendColorDodge:
3734 			mode = 10;
3735 			break;
3736 		case gfxBlendColorBurn:
3737 			mode = 11;
3738 			break;
3739 		case gfxBlendHue:
3740 			mode = 12;
3741 			break;
3742 		case gfxBlendSaturation:
3743 			mode = 13;
3744 			break;
3745 		case gfxBlendColor:
3746 			mode = 14;
3747 			break;
3748 		case gfxBlendLuminosity:
3749 			mode = 15;
3750 			break;
3751 	}
3752 	return mode;
3753 }
3754 
3755 void SlaOutputDev::applyMask(PageItem *ite)
3756 {
3757 	if (m_groupStack.count() != 0)
3758 	{
3759 		if (!m_groupStack.top().maskName.isEmpty())
3760 		{
3761 			ite->setPatternMask(m_groupStack.top().maskName);
3762 			QPointF maskPos = m_groupStack.top().maskPos;
3763 			double sx, sy, px, py, r, shx, shy;
3764 			ite->maskTransform(sx, sy, px, py, r, shx, shy);
3765 			ite->setMaskTransform(sx, sy, maskPos.x() - ite->xPos(), maskPos.y() - ite->yPos(), r, shx, shy);
3766 			if (m_groupStack.top().alpha)
3767 			{
3768 				if (m_groupStack.top().inverted)
3769 					ite->setMaskType(8);
3770 				else
3771 					ite->setMaskType(3);
3772 			}
3773 			else
3774 			{
3775 				if (m_groupStack.top().inverted)
3776 					ite->setMaskType(7);
3777 				else
3778 					ite->setMaskType(6);
3779 			}
3780 		}
3781 	}
3782 	// Code for updating our Progressbar, needs to be called this way, as we have no
3783 	// possibility to get the current fileposition.
3784 	updateGUICounter++;
3785 	if (updateGUICounter > 20)
3786 	{
3787 		qApp->processEvents();
3788 		updateGUICounter = 0;
3789 	}
3790 }
3791 
3792 void SlaOutputDev::pushGroup(const QString& maskName, GBool forSoftMask, GBool alpha, bool inverted)
3793 {
3794 	groupEntry gElements;
3795 	gElements.forSoftMask = forSoftMask;
3796 	gElements.alpha = alpha;
3797 	gElements.inverted = inverted;
3798 	gElements.maskName = maskName;
3799 	m_groupStack.push(gElements);
3800 }
3801 
3802 QString SlaOutputDev::UnicodeParsedString(POPPLER_CONST GooString *s1)
3803 {
3804 	if ( !s1 || s1->getLength() == 0 )
3805 		return QString();
3806 	GBool isUnicode;
3807 	int i;
3808 	Unicode u;
3809 	QString result;
3810 	if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getLength() > 1 && (s1->getChar(1) & 0xff) == 0xff))
3811 	{
3812 		isUnicode = gTrue;
3813 		i = 2;
3814 		result.reserve((s1->getLength() - 2) / 2);
3815 	}
3816 	else
3817 	{
3818 		isUnicode = gFalse;
3819 		i = 0;
3820 		result.reserve(s1->getLength());
3821 	}
3822 	while (i < s1->getLength())
3823 	{
3824 		if (isUnicode)
3825 		{
3826 			u = ((s1->getChar(i) & 0xff) << 8) | (s1->getChar(i+1) & 0xff);
3827 			i += 2;
3828 		}
3829 		else
3830 		{
3831 			u = s1->getChar(i) & 0xff;
3832 			++i;
3833 		}
3834 		result += QChar( u );
3835 	}
3836 	return result;
3837 }
3838 
3839 QString SlaOutputDev::UnicodeParsedString(const std::string& s1)
3840 {
3841 	if (s1.length() == 0)
3842 		return QString();
3843 	GBool isUnicode;
3844 	size_t i;
3845 	Unicode u;
3846 	QString result;
3847 	if ((s1.at(0) & 0xff) == 0xfe && (s1.length() > 1 && (s1.at(1) & 0xff) == 0xff))
3848 	{
3849 		isUnicode = gTrue;
3850 		i = 2;
3851 		result.reserve((s1.length() - 2) / 2);
3852 	}
3853 	else
3854 	{
3855 		isUnicode = gFalse;
3856 		i = 0;
3857 		result.reserve(s1.length());
3858 	}
3859 	while (i < s1.length())
3860 	{
3861 		if (isUnicode)
3862 		{
3863 			u = ((s1.at(i) & 0xff) << 8) | (s1.at(i+1) & 0xff);
3864 			i += 2;
3865 		}
3866 		else
3867 		{
3868 			u = s1.at(i) & 0xff;
3869 			++i;
3870 		}
3871 		// #15616: imagemagick may write unicode strings incorrectly in PDF
3872 		if (u == 0)
3873 			continue;
3874 		result += QChar(u);
3875 	}
3876 	return result;
3877 }
3878 
3879 bool SlaOutputDev::checkClip()
3880 {
3881 	bool ret = false;
3882 	if (!m_currentClipPath.isEmpty())
3883 	{
3884 		QRectF bbox = m_currentClipPath.boundingRect();
3885 		if ((bbox.width() > 0) && (bbox.height() > 0))
3886 			ret = true;
3887 	}
3888 	return ret;
3889 }
3890 
3891 void SlaOutputDev::setItemFillAndStroke(GfxState* state, PageItem* textNode)
3892 {
3893 
3894 	textNode->ClipEdited = true;
3895 	textNode->FrameType = 3;
3896 	textNode->setLineEnd(m_lineEnd);
3897 	textNode->setLineJoin(m_lineJoin);
3898 	textNode->setTextFlowMode(PageItem::TextFlowDisabled);
3899 
3900 	int textRenderingMode = state->getRender();
3901 	// Invisible or only used for clipping
3902 	if (textRenderingMode == 3)
3903 		return;
3904 
3905 	// Fill text rendering modes. See above
3906 	if (textRenderingMode == 0 || textRenderingMode == 2 || textRenderingMode == 4 || textRenderingMode == 6)
3907 	{
3908 		m_currColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &m_currFillShade);
3909 		if (textNode->isTextFrame())
3910 		{
3911 			textNode->setFillTransparency(1.0 - (state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity())); //fill colour sets the background colour for the frame not the fill colour fore  the text
3912 			textNode->setLineTransparency(1.0); // this sets the transparency of the textbox border and we don't want to see it
3913 			textNode->setFillColor(CommonStrings::None);
3914 			textNode->setLineColor(CommonStrings::None);
3915 			textNode->setLineWidth(0);//line  width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth());
3916 			textNode->setFillShade(m_currFillShade);
3917 		}
3918 		else
3919 		{
3920 			textNode->setFillColor(m_currColorFill);
3921 			textNode->setFillShade(m_currFillShade);
3922 			textNode->setFillEvenOdd(false);
3923 			textNode->setFillTransparency(1.0 - state->getFillOpacity());
3924 			textNode->setFillBlendmode(getBlendMode(state));
3925 		}
3926 	}
3927 	// Stroke text rendering modes. See above
3928 	if (textRenderingMode == 1 || textRenderingMode == 2 || textRenderingMode == 5 || textRenderingMode == 6)
3929 	{
3930 		m_currColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &m_currStrokeShade);
3931 		if (textNode->isTextFrame())
3932 		{
3933 			//fill color sets the background color for the frame not the fill color fore  the text
3934 			textNode->setFillTransparency(1.0 - (state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity()));
3935 			textNode->setLineTransparency(1.0); // this sets the transparency of the textbox border and we don't want to see it
3936 			textNode->setFillColor(CommonStrings::None); //TODO: Check if we override the stroke color with the fill color when there is a choice
3937 			textNode->setLineColor(CommonStrings::None);
3938 			textNode->setLineWidth(0);//line  width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth());
3939 			textNode->setFillBlendmode(getBlendMode(state));
3940 			textNode->setFillShade(m_currFillShade);
3941 		}
3942 		else
3943 		{
3944 			textNode->setLineColor(m_currColorStroke);
3945 			textNode->setLineWidth(0);//line  width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth());
3946 			textNode->setFillTransparency(1.0 - state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity());
3947 			textNode->setLineTransparency(1.0); // this sets the transparency of the textbox border and we don't want to see it
3948 			textNode->setLineBlendmode(getBlendMode(state));
3949 			textNode->setLineShade(m_currStrokeShade);
3950 		}
3951 	}
3952 }
3953