Rev 24236 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
19590 | jghali | 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" |
||
22513 | jghali | 9 | |
19590 | jghali | 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 | |||
23550 | jghali | 23 | namespace |
24 | { |
||
25 | // Compute the intersection of two paths while considering the fillrule of each of them. |
||
26 | // QPainterPath has the right interface to do the operation but is currently buggy. |
||
27 | // See for example https://bugreports.qt.io/browse/QTBUG-83102. Thus this function |
||
28 | // applies some heuristics to find the best result. As soon QPainterPath is fixed |
||
29 | // one can just use a.intersected(b) wherever this function is called. |
||
30 | // TODO: Find an alternative to QPainterPath that works for different fill rules. |
||
31 | QPainterPath intersection(QPainterPath const &a, QPainterPath const &b) |
||
32 | { |
||
33 | // An empty path is treated like the whole area. |
||
34 | if (a.elementCount() == 0) |
||
35 | return b; |
||
36 | if (b.elementCount() == 0) |
||
37 | return a; |
||
38 | |||
39 | QPainterPath ret_a = a.intersected(b); |
||
40 | QPainterPath ret_b = b.intersected(a); |
||
41 | // Sometimes the resulting paths are not closed even though they should. |
||
42 | // Close them now. |
||
43 | ret_a.closeSubpath(); |
||
44 | ret_b.closeSubpath(); |
||
45 | |||
46 | // Most of the time one of the two operations returns an empty path while the other |
||
47 | // gives us the desired result. Return the non-empty one. |
||
48 | if (ret_a.elementCount() == 0) |
||
49 | return ret_b; |
||
50 | if (ret_b.elementCount() == 0) |
||
51 | return ret_a; |
||
52 | |||
53 | // There are cases where both intersections are not empty but one of them is quite |
||
54 | // complicated with several subpaths, etc. We return the simpler one. |
||
55 | return (ret_a.elementCount() <= ret_b.elementCount()) ? ret_a : ret_b; |
||
56 | } |
||
23589 | jghali | 57 | |
58 | // Invert preblending matte values into the color values. Assuming that c and alpha are RGBA components |
||
59 | // between 0 and 255. |
||
60 | int unblendMatte(int c, int alpha, int matte) |
||
61 | { |
||
62 | if (alpha == 0) |
||
63 | return matte; |
||
64 | int ret = matte + ((c - matte) * 255) / alpha; |
||
65 | if (ret < 0) |
||
66 | return 0; |
||
67 | if (ret > 255) |
||
68 | return 255; |
||
69 | return ret; |
||
70 | } |
||
23550 | jghali | 71 | } |
72 | |||
19590 | jghali | 73 | LinkSubmitForm::LinkSubmitForm(Object *actionObj) |
74 | { |
||
23377 | craig | 75 | if (!actionObj->isDict()) |
76 | return; |
||
22738 | jghali | 77 | |
23377 | craig | 78 | Object obj1 = actionObj->dictLookup("F"); |
79 | if (!obj1.isNull()) |
||
19590 | jghali | 80 | { |
23377 | craig | 81 | if (obj1.isDict()) |
22154 | jghali | 82 | { |
23377 | craig | 83 | Object obj3 = obj1.dictLookup("FS"); |
84 | if (!obj3.isNull()) |
||
22154 | jghali | 85 | { |
23377 | craig | 86 | if (obj3.isName()) |
22154 | jghali | 87 | { |
23377 | craig | 88 | POPPLER_CONST char *name = obj3.getName(); |
89 | if (!strcmp(name, "URL")) |
||
22154 | jghali | 90 | { |
23377 | craig | 91 | Object obj2 = obj1.dictLookup("F"); |
92 | if (!obj2.isNull()) |
||
93 | fileName = obj2.getString()->copy(); |
||
22154 | jghali | 94 | } |
95 | } |
||
96 | } |
||
97 | } |
||
98 | } |
||
23377 | craig | 99 | obj1 = actionObj->dictLookup("Flags"); |
100 | if (!obj1.isNull()) |
||
101 | { |
||
102 | if (obj1.isNum()) |
||
103 | m_flags = obj1.getInt(); |
||
104 | } |
||
19590 | jghali | 105 | } |
106 | |||
107 | LinkSubmitForm::~LinkSubmitForm() |
||
108 | { |
||
22609 | craig | 109 | delete fileName; |
19590 | jghali | 110 | } |
111 | |||
112 | LinkImportData::LinkImportData(Object *actionObj) |
||
113 | { |
||
23377 | craig | 114 | if (!actionObj->isDict()) |
115 | return; |
||
116 | Object obj1 = actionObj->dictLookup("F"); |
||
117 | if (obj1.isNull()) |
||
118 | return; |
||
22738 | jghali | 119 | |
23377 | craig | 120 | Object obj3 = getFileSpecNameForPlatform(&obj1); |
121 | if (!obj3.isNull()) |
||
122 | fileName = obj3.getString()->copy(); |
||
19590 | jghali | 123 | } |
124 | |||
125 | LinkImportData::~LinkImportData() |
||
126 | { |
||
22609 | craig | 127 | delete fileName; |
19590 | jghali | 128 | } |
129 | |||
130 | AnoOutputDev::~AnoOutputDev() |
||
131 | { |
||
22609 | craig | 132 | delete m_fontName; |
133 | delete m_itemText; |
||
19590 | jghali | 134 | } |
135 | |||
136 | AnoOutputDev::AnoOutputDev(ScribusDoc* doc, QStringList *importedColors) |
||
137 | { |
||
138 | m_doc = doc; |
||
139 | m_importedColors = importedColors; |
||
23377 | craig | 140 | CurrColorText = "Black"; |
141 | CurrColorFill = CommonStrings::None; |
||
19590 | jghali | 142 | CurrColorStroke = CommonStrings::None; |
143 | } |
||
144 | |||
145 | void AnoOutputDev::eoFill(GfxState *state) |
||
146 | { |
||
147 | int shade = 100; |
||
148 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
149 | } |
||
150 | |||
151 | void AnoOutputDev::fill(GfxState *state) |
||
152 | { |
||
153 | int shade = 100; |
||
154 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
155 | } |
||
156 | |||
157 | void AnoOutputDev::stroke(GfxState *state) |
||
158 | { |
||
159 | int shade = 100; |
||
160 | CurrColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &shade); |
||
161 | } |
||
162 | |||
22678 | jghali | 163 | void AnoOutputDev::drawString(GfxState *state, POPPLER_CONST GooString *s) |
19590 | jghali | 164 | { |
165 | int shade = 100; |
||
166 | CurrColorText = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
167 | m_fontSize = state->getFontSize(); |
||
168 | if (state->getFont()) |
||
169 | m_fontName = state->getFont()->getName()->copy(); |
||
170 | m_itemText = s->copy(); |
||
171 | } |
||
172 | |||
22741 | jghali | 173 | QString AnoOutputDev::getColor(GfxColorSpace *color_space, POPPLER_CONST_070 GfxColor *color, int *shade) |
19590 | jghali | 174 | { |
175 | QString fNam; |
||
176 | QString namPrefix = "FromPDF"; |
||
177 | ScColor tmp; |
||
178 | tmp.setSpotColor(false); |
||
179 | tmp.setRegistrationColor(false); |
||
180 | *shade = 100; |
||
181 | if ((color_space->getMode() == csDeviceRGB) || (color_space->getMode() == csCalRGB)) |
||
182 | { |
||
183 | GfxRGB rgb; |
||
184 | color_space->getRGB(color, &rgb); |
||
22212 | jghali | 185 | double Rc = colToDbl(rgb.r); |
186 | double Gc = colToDbl(rgb.g); |
||
187 | double Bc = colToDbl(rgb.b); |
||
188 | tmp.setRgbColorF(Rc, Gc, Bc); |
||
19590 | jghali | 189 | fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp); |
190 | } |
||
191 | else if (color_space->getMode() == csDeviceCMYK) |
||
192 | { |
||
193 | GfxCMYK cmyk; |
||
194 | color_space->getCMYK(color, &cmyk); |
||
22212 | jghali | 195 | double Cc = colToDbl(cmyk.c); |
196 | double Mc = colToDbl(cmyk.m); |
||
197 | double Yc = colToDbl(cmyk.y); |
||
198 | double Kc = colToDbl(cmyk.k); |
||
22593 | jghali | 199 | tmp.setCmykColorF(Cc, Mc, Yc, Kc); |
19590 | jghali | 200 | fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp); |
201 | } |
||
202 | else if ((color_space->getMode() == csCalGray) || (color_space->getMode() == csDeviceGray)) |
||
203 | { |
||
204 | GfxGray gray; |
||
205 | color_space->getGray(color, &gray); |
||
22212 | jghali | 206 | double Kc = 1.0 - colToDbl(gray); |
22593 | jghali | 207 | tmp.setCmykColorF(0, 0, 0, Kc); |
19590 | jghali | 208 | fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp); |
209 | } |
||
210 | else if (color_space->getMode() == csSeparation) |
||
211 | { |
||
22596 | jghali | 212 | GfxSeparationColorSpace* sepColorSpace = (GfxSeparationColorSpace*)color_space; |
213 | GfxColorSpace* altColorSpace = sepColorSpace->getAlt(); |
||
214 | QString name = QString(sepColorSpace->getName()->getCString()); |
||
215 | bool isRegistrationColor = (name == "All"); |
||
216 | if (isRegistrationColor) |
||
217 | { |
||
218 | tmp.setCmykColorF(1.0, 1.0, 1.0, 1.0); |
||
219 | tmp.setRegistrationColor(true); |
||
220 | name = "Registration"; |
||
221 | } |
||
222 | else if ((altColorSpace->getMode() == csDeviceRGB) || (altColorSpace->getMode() == csCalRGB)) |
||
223 | { |
||
224 | double x = 1.0; |
||
225 | double comps[gfxColorMaxComps]; |
||
226 | sepColorSpace->getFunc()->transform(&x, comps); |
||
227 | tmp.setRgbColorF(comps[0], comps[1], comps[2]); |
||
228 | } |
||
229 | else if ((altColorSpace->getMode() == csCalGray) || (altColorSpace->getMode() == csDeviceGray)) |
||
230 | { |
||
231 | double x = 1.0; |
||
232 | double comps[gfxColorMaxComps]; |
||
233 | sepColorSpace->getFunc()->transform(&x, comps); |
||
234 | tmp.setCmykColorF(0.0, 0.0, 0.0, 1.0 - comps[0]); |
||
235 | } |
||
236 | else if (altColorSpace->getMode() == csLab) |
||
237 | { |
||
238 | double x = 1.0; |
||
239 | double comps[gfxColorMaxComps]; |
||
240 | sepColorSpace->getFunc()->transform(&x, comps); |
||
241 | tmp.setLabColor(comps[0], comps[1], comps[2]); |
||
242 | } |
||
243 | else |
||
244 | { |
||
245 | GfxCMYK cmyk; |
||
246 | color_space->getCMYK(color, &cmyk); |
||
247 | double Cc = colToDbl(cmyk.c); |
||
248 | double Mc = colToDbl(cmyk.m); |
||
249 | double Yc = colToDbl(cmyk.y); |
||
250 | double Kc = colToDbl(cmyk.k); |
||
251 | tmp.setCmykColorF(Cc, Mc, Yc, Kc); |
||
252 | } |
||
253 | tmp.setSpotColor(true); |
||
22592 | jghali | 254 | |
22596 | jghali | 255 | fNam = m_doc->PageColors.tryAddColor(name, tmp); |
256 | *shade = qRound(colToDbl(color->c[0]) * 100); |
||
19590 | jghali | 257 | } |
258 | else |
||
259 | { |
||
260 | GfxRGB rgb; |
||
261 | color_space->getRGB(color, &rgb); |
||
22212 | jghali | 262 | double Rc = colToDbl(rgb.r); |
263 | double Gc = colToDbl(rgb.g); |
||
264 | double Bc = colToDbl(rgb.b); |
||
265 | tmp.setRgbColorF(Rc, Gc, Bc); |
||
19590 | jghali | 266 | fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp); |
267 | // qDebug() << "update fill color other colorspace" << color_space->getMode() << "treating as rgb" << Rc << Gc << Bc; |
||
268 | } |
||
269 | if (fNam == namPrefix+tmp.name()) |
||
270 | m_importedColors->append(fNam); |
||
271 | return fNam; |
||
272 | } |
||
273 | |||
274 | SlaOutputDev::SlaOutputDev(ScribusDoc* doc, QList<PageItem*> *Elements, QStringList *importedColors, int flags) |
||
275 | { |
||
276 | m_doc = doc; |
||
277 | m_Elements = Elements; |
||
278 | pushGroup(); |
||
279 | m_importedColors = importedColors; |
||
280 | CurrColorStroke = "Black"; |
||
281 | CurrColorFill = "Black"; |
||
282 | tmpSel = new Selection(m_doc, false); |
||
283 | importerFlags = flags; |
||
284 | currentLayer = m_doc->activeLayer(); |
||
285 | layersSetByOCG = false; |
||
286 | } |
||
287 | |||
288 | SlaOutputDev::~SlaOutputDev() |
||
289 | { |
||
290 | m_groupStack.clear(); |
||
291 | tmpSel->clear(); |
||
292 | delete tmpSel; |
||
293 | delete m_fontEngine; |
||
294 | } |
||
295 | |||
296 | /* get Actions not implemented by Poppler */ |
||
297 | LinkAction* SlaOutputDev::SC_getAction(AnnotWidget *ano) |
||
298 | { |
||
22527 | craig | 299 | LinkAction *linkAction = nullptr; |
19590 | jghali | 300 | Object obj; |
301 | Ref refa = ano->getRef(); |
||
22906 | jghali | 302 | |
22154 | jghali | 303 | obj = xref->fetch(refa.num, refa.gen); |
304 | if (obj.isDict()) |
||
305 | { |
||
306 | Dict* adic = obj.getDict(); |
||
22906 | jghali | 307 | POPPLER_CONST_075 Object POPPLER_REF additionalActions = adic->lookupNF("A"); |
22154 | jghali | 308 | Object additionalActionsObject = additionalActions.fetch(pdfDoc->getXRef()); |
309 | if (additionalActionsObject.isDict()) |
||
310 | { |
||
311 | Object actionObject = additionalActionsObject.dictLookup("S"); |
||
312 | if (actionObject.isName("ImportData")) |
||
313 | { |
||
314 | linkAction = new LinkImportData(&additionalActionsObject); |
||
315 | } |
||
316 | else if (actionObject.isName("SubmitForm")) |
||
317 | { |
||
318 | linkAction = new LinkSubmitForm(&additionalActionsObject); |
||
319 | } |
||
320 | } |
||
321 | } |
||
19590 | jghali | 322 | return linkAction; |
323 | } |
||
324 | |||
325 | /* Replacement for the crippled Poppler function LinkAction* AnnotWidget::getAdditionalAction(AdditionalActionsType type) */ |
||
23478 | jghali | 326 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
327 | std::unique_ptr<LinkAction> SlaOutputDev::SC_getAdditionalAction(const char *key, AnnotWidget *ano) |
||
328 | { |
||
329 | std::unique_ptr<LinkAction> linkAction; |
||
330 | #else |
||
19590 | jghali | 331 | LinkAction* SlaOutputDev::SC_getAdditionalAction(const char *key, AnnotWidget *ano) |
332 | { |
||
22527 | craig | 333 | LinkAction *linkAction = nullptr; |
23478 | jghali | 334 | #endif |
19590 | jghali | 335 | Object obj; |
336 | Ref refa = ano->getRef(); |
||
22154 | jghali | 337 | |
338 | obj = xref->fetch(refa.num, refa.gen); |
||
339 | if (obj.isDict()) |
||
340 | { |
||
341 | Dict* adic = obj.getDict(); |
||
22906 | jghali | 342 | POPPLER_CONST_075 Object POPPLER_REF additionalActions = adic->lookupNF("AA"); |
22154 | jghali | 343 | Object additionalActionsObject = additionalActions.fetch(pdfDoc->getXRef()); |
344 | if (additionalActionsObject.isDict()) |
||
345 | { |
||
346 | Object actionObject = additionalActionsObject.dictLookup(key); |
||
347 | if (actionObject.isDict()) |
||
348 | linkAction = LinkAction::parseAction(&actionObject, pdfDoc->getCatalog()->getBaseURI()); |
||
349 | } |
||
350 | } |
||
19590 | jghali | 351 | return linkAction; |
352 | } |
||
353 | |||
354 | GBool SlaOutputDev::annotations_callback(Annot *annota, void *user_data) |
||
355 | { |
||
356 | SlaOutputDev *dev = (SlaOutputDev*)user_data; |
||
357 | PDFRectangle *box = annota->getRect(); |
||
358 | double xCoor = dev->m_doc->currentPage()->xOffset() + box->x1 - dev->cropOffsetX; |
||
359 | double yCoor = dev->m_doc->currentPage()->yOffset() + dev->m_doc->currentPage()->height() - box->y2 + dev->cropOffsetY; |
||
360 | double width = box->x2 - box->x1; |
||
361 | double height = box->y2 - box->y1; |
||
362 | if (dev->rotate == 90) |
||
363 | { |
||
364 | xCoor = dev->m_doc->currentPage()->xOffset() - dev->cropOffsetX + box->y2; |
||
365 | yCoor = dev->m_doc->currentPage()->yOffset() + dev->cropOffsetY + box->x1; |
||
366 | } |
||
367 | else if (dev->rotate == 180) |
||
368 | { |
||
369 | xCoor = dev->m_doc->currentPage()->xOffset() - dev->cropOffsetX + dev->m_doc->currentPage()->width() - box->x1; |
||
370 | yCoor = dev->m_doc->currentPage()->yOffset() + dev->cropOffsetY + box->y2; |
||
371 | } |
||
372 | else if (dev->rotate == 270) |
||
373 | { |
||
374 | xCoor = dev->m_doc->currentPage()->xOffset() - dev->cropOffsetX + dev->m_doc->currentPage()->width() - box->y2; |
||
375 | yCoor = dev->m_doc->currentPage()->yOffset() + dev->cropOffsetY + dev->m_doc->currentPage()->height() - box->x1; |
||
376 | } |
||
377 | bool retVal = true; |
||
378 | if (annota->getType() == Annot::typeText) |
||
379 | retVal = !dev->handleTextAnnot(annota, xCoor, yCoor, width, height); |
||
380 | else if (annota->getType() == Annot::typeLink) |
||
381 | retVal = !dev->handleLinkAnnot(annota, xCoor, yCoor, width, height); |
||
382 | else if (annota->getType() == Annot::typeWidget) |
||
383 | retVal = !dev->handleWidgetAnnot(annota, xCoor, yCoor, width, height); |
||
384 | return retVal; |
||
385 | } |
||
386 | |||
387 | bool SlaOutputDev::handleTextAnnot(Annot* annota, double xCoor, double yCoor, double width, double height) |
||
388 | { |
||
389 | AnnotText *anl = (AnnotText*)annota; |
||
20561 | jghali | 390 | int z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, CommonStrings::None, CommonStrings::None); |
19590 | jghali | 391 | PageItem *ite = m_doc->Items->at(z); |
392 | int flg = annota->getFlags(); |
||
393 | if (!(flg & 16)) |
||
394 | ite->setRotation(rotate, true); |
||
395 | ite->ClipEdited = true; |
||
396 | ite->FrameType = 3; |
||
397 | ite->setFillEvenOdd(false); |
||
23040 | jghali | 398 | ite->Clip = flattenPath(ite->PoLine, ite->Segments); |
19590 | jghali | 399 | ite->ContourLine = ite->PoLine.copy(); |
400 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
401 | m_Elements->append(ite); |
||
402 | if (m_groupStack.count() != 0) |
||
403 | { |
||
404 | m_groupStack.top().Items.append(ite); |
||
405 | applyMask(ite); |
||
406 | } |
||
407 | ite->setIsAnnotation(true); |
||
408 | ite->AutoName = false; |
||
409 | ite->annotation().setType(Annotation::Text); |
||
410 | ite->annotation().setActionType(Annotation::Action_None); |
||
411 | ite->annotation().setAnOpen(anl->getOpen()); |
||
412 | QString iconName = UnicodeParsedString(anl->getIcon()); |
||
413 | if (iconName == "Note") |
||
414 | ite->annotation().setIcon(Annotation::Icon_Note); |
||
415 | else if (iconName == "Comment") |
||
416 | ite->annotation().setIcon(Annotation::Icon_Comment); |
||
417 | else if (iconName == "Key") |
||
418 | ite->annotation().setIcon(Annotation::Icon_Key); |
||
419 | else if (iconName == "Help") |
||
420 | ite->annotation().setIcon(Annotation::Icon_Help); |
||
421 | else if (iconName == "NewParagraph") |
||
422 | ite->annotation().setIcon(Annotation::Icon_NewParagraph); |
||
423 | else if (iconName == "Paragraph") |
||
424 | ite->annotation().setIcon(Annotation::Icon_Paragraph); |
||
425 | else if (iconName == "Insert") |
||
426 | ite->annotation().setIcon(Annotation::Icon_Insert); |
||
427 | else if (iconName == "Cross") |
||
428 | ite->annotation().setIcon(Annotation::Icon_Cross); |
||
429 | else if (iconName == "Circle") |
||
430 | ite->annotation().setIcon(Annotation::Icon_Circle); |
||
431 | else |
||
432 | ite->annotation().setIcon(Annotation::Icon_Note); |
||
433 | ite->setItemName( CommonStrings::itemName_TextAnnotation + QString("%1").arg(m_doc->TotalItems)); |
||
434 | ite->itemText.insertChars(UnicodeParsedString(annota->getContents())); |
||
435 | ite->itemText.trim(); |
||
436 | return true; |
||
437 | } |
||
438 | |||
439 | bool SlaOutputDev::handleLinkAnnot(Annot* annota, double xCoor, double yCoor, double width, double height) |
||
440 | { |
||
441 | AnnotLink *anl = (AnnotLink*)annota; |
||
442 | LinkAction *act = anl->getAction(); |
||
443 | if (!act) |
||
444 | return false; |
||
445 | bool validLink = false; |
||
446 | int pagNum = 0; |
||
447 | int xco = 0; |
||
448 | int yco = 0; |
||
449 | QString fileName = ""; |
||
450 | if (act->getKind() == actionGoTo) |
||
451 | { |
||
22513 | jghali | 452 | LinkGoTo *gto = (LinkGoTo*) act; |
453 | POPPLER_CONST LinkDest *dst = gto->getDest(); |
||
19590 | jghali | 454 | if (dst) |
455 | { |
||
456 | if (dst->getKind() == destXYZ) |
||
457 | { |
||
458 | if (dst->isPageRef()) |
||
459 | { |
||
460 | Ref dstr = dst->getPageRef(); |
||
22975 | jghali | 461 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 76, 0) |
462 | pagNum = pdfDoc->findPage(dstr); |
||
463 | #else |
||
19590 | jghali | 464 | pagNum = pdfDoc->findPage(dstr.num, dstr.gen); |
22975 | jghali | 465 | #endif |
19590 | jghali | 466 | } |
467 | else |
||
468 | pagNum = dst->getPageNum(); |
||
469 | xco = dst->getLeft(); |
||
470 | yco = dst->getTop(); |
||
471 | validLink = true; |
||
472 | } |
||
473 | } |
||
474 | else |
||
475 | { |
||
22513 | jghali | 476 | POPPLER_CONST GooString *ndst = gto->getNamedDest(); |
19590 | jghali | 477 | if (ndst) |
478 | { |
||
23478 | jghali | 479 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
480 | std::unique_ptr<LinkDest> dstn = pdfDoc->findDest(ndst); |
||
481 | #else |
||
19590 | jghali | 482 | LinkDest *dstn = pdfDoc->findDest(ndst); |
23478 | jghali | 483 | #endif |
19590 | jghali | 484 | if (dstn) |
485 | { |
||
486 | if (dstn->getKind() == destXYZ) |
||
487 | { |
||
488 | if (dstn->isPageRef()) |
||
489 | { |
||
490 | Ref dstr = dstn->getPageRef(); |
||
22975 | jghali | 491 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 76, 0) |
492 | pagNum = pdfDoc->findPage(dstr); |
||
493 | #else |
||
19590 | jghali | 494 | pagNum = pdfDoc->findPage(dstr.num, dstr.gen); |
22975 | jghali | 495 | #endif |
19590 | jghali | 496 | } |
497 | else |
||
498 | pagNum = dstn->getPageNum(); |
||
499 | xco = dstn->getLeft(); |
||
500 | yco = dstn->getTop(); |
||
501 | validLink = true; |
||
502 | } |
||
503 | } |
||
504 | } |
||
505 | } |
||
506 | } |
||
507 | else if (act->getKind() == actionGoToR) |
||
508 | { |
||
509 | LinkGoToR *gto = (LinkGoToR*)act; |
||
510 | fileName = UnicodeParsedString(gto->getFileName()); |
||
22513 | jghali | 511 | POPPLER_CONST LinkDest *dst = gto->getDest(); |
19590 | jghali | 512 | if (dst) |
513 | { |
||
514 | if (dst->getKind() == destXYZ) |
||
515 | { |
||
516 | pagNum = dst->getPageNum(); |
||
517 | xco = dst->getLeft(); |
||
518 | yco = dst->getTop(); |
||
519 | validLink = true; |
||
520 | } |
||
521 | } |
||
522 | else |
||
523 | { |
||
22513 | jghali | 524 | POPPLER_CONST GooString *ndst = gto->getNamedDest(); |
19590 | jghali | 525 | if (ndst) |
526 | { |
||
23478 | jghali | 527 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
528 | std::unique_ptr<LinkDest> dstn = pdfDoc->findDest(ndst); |
||
529 | #else |
||
19590 | jghali | 530 | LinkDest *dstn = pdfDoc->findDest(ndst); |
23478 | jghali | 531 | #endif |
19590 | jghali | 532 | if (dstn) |
533 | { |
||
534 | if (dstn->getKind() == destXYZ) |
||
535 | { |
||
536 | pagNum = dstn->getPageNum(); |
||
537 | xco = dstn->getLeft(); |
||
538 | yco = dstn->getTop(); |
||
539 | validLink = true; |
||
540 | } |
||
541 | } |
||
542 | } |
||
543 | } |
||
544 | } |
||
545 | else if (act->getKind() == actionURI) |
||
546 | { |
||
547 | LinkURI *gto = (LinkURI*)act; |
||
548 | validLink = true; |
||
549 | fileName = UnicodeParsedString(gto->getURI()); |
||
550 | } |
||
551 | if (validLink) |
||
552 | { |
||
20561 | jghali | 553 | int z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, CommonStrings::None, CommonStrings::None); |
19590 | jghali | 554 | PageItem *ite = m_doc->Items->at(z); |
555 | int flg = annota->getFlags(); |
||
556 | if (!(flg & 16)) |
||
557 | ite->setRotation(rotate, true); |
||
558 | ite->ClipEdited = true; |
||
559 | ite->FrameType = 3; |
||
560 | ite->setFillEvenOdd(false); |
||
23040 | jghali | 561 | ite->Clip = flattenPath(ite->PoLine, ite->Segments); |
19590 | jghali | 562 | ite->ContourLine = ite->PoLine.copy(); |
563 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
564 | m_Elements->append(ite); |
||
565 | if (m_groupStack.count() != 0) |
||
566 | { |
||
567 | m_groupStack.top().Items.append(ite); |
||
568 | applyMask(ite); |
||
569 | } |
||
570 | ite->setIsAnnotation(true); |
||
571 | ite->AutoName = false; |
||
572 | if (act->getKind() == actionGoTo) |
||
573 | { |
||
21458 | jghali | 574 | ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1)); |
19590 | jghali | 575 | ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco)); |
576 | ite->annotation().setActionType(2); |
||
577 | } |
||
578 | else if (act->getKind() == actionGoToR) |
||
579 | { |
||
21458 | jghali | 580 | ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1)); |
19590 | jghali | 581 | ite->annotation().setExtern(fileName); |
582 | ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco)); |
||
583 | ite->annotation().setActionType(9); |
||
584 | } |
||
585 | else if (act->getKind() == actionURI) |
||
586 | { |
||
587 | ite->annotation().setAction(""); |
||
588 | ite->annotation().setExtern(fileName); |
||
589 | ite->annotation().setActionType(8); |
||
590 | } |
||
591 | ite->annotation().setType(Annotation::Link); |
||
592 | ite->setItemName( CommonStrings::itemName_LinkAnnotation + QString("%1").arg(m_doc->TotalItems)); |
||
593 | } |
||
594 | return validLink; |
||
595 | } |
||
596 | |||
597 | bool SlaOutputDev::handleWidgetAnnot(Annot* annota, double xCoor, double yCoor, double width, double height) |
||
598 | { |
||
599 | bool retVal = false; |
||
600 | bool found = false; |
||
601 | |||
602 | if (!m_formWidgets) |
||
603 | return false; |
||
604 | |||
605 | int formcount = m_formWidgets->getNumWidgets(); |
||
606 | for (int i = 0; i < formcount; ++i) |
||
607 | { |
||
608 | FormWidget *fm = m_formWidgets->getWidget(i); |
||
609 | if (!fm) |
||
610 | continue; |
||
611 | AnnotWidget *ano = fm->getWidgetAnnotation(); |
||
612 | if (!ano) |
||
613 | continue; |
||
614 | if (ano != (AnnotWidget*) annota) |
||
615 | continue; |
||
616 | found = true; |
||
617 | int wtyp = -1; |
||
618 | if (fm->getType() == formButton) |
||
619 | { |
||
620 | FormWidgetButton *btn = (FormWidgetButton*)fm; |
||
621 | if (btn) |
||
622 | { |
||
623 | if (btn->getButtonType() == formButtonCheck) |
||
624 | { |
||
625 | wtyp = Annotation::Checkbox; |
||
626 | retVal = true; |
||
627 | } |
||
628 | else if (btn->getButtonType() == formButtonPush) |
||
629 | { |
||
630 | wtyp = Annotation::Button; |
||
631 | retVal = true; |
||
632 | } |
||
633 | else if (btn->getButtonType() == formButtonRadio) |
||
634 | { |
||
635 | wtyp = Annotation::RadioButton; |
||
636 | retVal = true; |
||
637 | } |
||
638 | } |
||
639 | } |
||
640 | else if (fm->getType() == formText) |
||
641 | { |
||
642 | wtyp = Annotation::Textfield; |
||
643 | retVal = true; |
||
644 | } |
||
645 | else if (fm->getType() == formChoice) |
||
646 | { |
||
647 | FormWidgetChoice *btn = (FormWidgetChoice*)fm; |
||
648 | if (btn) |
||
649 | { |
||
650 | if (btn->isCombo()) |
||
651 | { |
||
652 | wtyp = Annotation::Combobox; |
||
653 | retVal = true; |
||
654 | } |
||
655 | else if (btn->isListBox()) |
||
656 | { |
||
657 | wtyp = Annotation::Listbox; |
||
658 | retVal = true; |
||
659 | } |
||
660 | } |
||
661 | } |
||
662 | if (retVal) |
||
663 | { |
||
664 | AnnotAppearanceCharacs *achar = ano->getAppearCharacs(); |
||
665 | bool fgFound = false; |
||
666 | bool bgFound = false; |
||
667 | if (achar) |
||
668 | { |
||
22513 | jghali | 669 | POPPLER_CONST AnnotColor *bgCol = achar->getBackColor(); |
19590 | jghali | 670 | if (bgCol) |
671 | { |
||
672 | bgFound = true; |
||
673 | CurrColorFill = getAnnotationColor(bgCol); |
||
674 | } |
||
675 | else |
||
676 | CurrColorFill = CommonStrings::None; |
||
22513 | jghali | 677 | POPPLER_CONST AnnotColor *fgCol = achar->getBorderColor(); |
19590 | jghali | 678 | if (fgCol) |
679 | { |
||
680 | fgFound = true; |
||
681 | CurrColorStroke = getAnnotationColor(fgCol); |
||
682 | } |
||
683 | else |
||
684 | { |
||
685 | fgCol = achar->getBackColor(); |
||
686 | if (fgCol) |
||
687 | CurrColorStroke = getAnnotationColor(fgCol); |
||
688 | else |
||
689 | CurrColorStroke = CommonStrings::None; |
||
690 | } |
||
691 | } |
||
692 | QString CurrColorText = "Black"; |
||
693 | double fontSize = 12; |
||
694 | QString fontName = ""; |
||
695 | QString itemText = ""; |
||
696 | AnnotAppearance *apa = annota->getAppearStreams(); |
||
697 | if (apa || !achar) |
||
698 | { |
||
699 | AnoOutputDev *Adev = new AnoOutputDev(m_doc, m_importedColors); |
||
22738 | jghali | 700 | Gfx *gfx = new Gfx(pdfDoc, Adev, pdfDoc->getPage(m_actPage)->getResourceDict(), annota->getRect(), nullptr); |
19590 | jghali | 701 | ano->draw(gfx, false); |
702 | if (!bgFound) |
||
703 | CurrColorFill = Adev->CurrColorFill; |
||
704 | if (!fgFound) |
||
705 | CurrColorStroke = Adev->CurrColorStroke; |
||
706 | CurrColorText = Adev->CurrColorText; |
||
707 | fontSize = Adev->m_fontSize; |
||
708 | fontName = UnicodeParsedString(Adev->m_fontName); |
||
709 | itemText = UnicodeParsedString(Adev->m_itemText); |
||
710 | delete gfx; |
||
711 | delete Adev; |
||
712 | } |
||
20561 | jghali | 713 | int z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, width, height, 0, CurrColorFill, CommonStrings::None); |
19590 | jghali | 714 | PageItem *ite = m_doc->Items->at(z); |
715 | int flg = annota->getFlags(); |
||
716 | if (!(flg & 16)) |
||
717 | ite->setRotation(rotate, true); |
||
718 | ite->ClipEdited = true; |
||
719 | ite->FrameType = 3; |
||
720 | ite->setFillEvenOdd(false); |
||
23040 | jghali | 721 | ite->Clip = flattenPath(ite->PoLine, ite->Segments); |
19590 | jghali | 722 | ite->ContourLine = ite->PoLine.copy(); |
723 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
724 | m_Elements->append(ite); |
||
725 | if (m_groupStack.count() != 0) |
||
726 | { |
||
727 | m_groupStack.top().Items.append(ite); |
||
728 | applyMask(ite); |
||
729 | } |
||
730 | ite->setIsAnnotation(true); |
||
731 | ite->AutoName = false; |
||
732 | AnnotBorder *brd = annota->getBorder(); |
||
733 | if (brd) |
||
734 | { |
||
735 | int bsty = brd->getStyle(); |
||
736 | if (bsty == AnnotBorder::borderDashed) |
||
737 | bsty = 1; |
||
738 | else if (bsty == AnnotBorder::borderBeveled) |
||
739 | bsty = 3; |
||
740 | else if (bsty == AnnotBorder::borderInset) |
||
741 | bsty = 4; |
||
742 | else if (bsty == AnnotBorder::borderUnderlined) |
||
743 | bsty = 2; |
||
22748 | jghali | 744 | ite->annotation().setBorderStyle(bsty); |
19590 | jghali | 745 | ite->annotation().setBorderColor(CurrColorStroke); |
22748 | jghali | 746 | ite->annotation().setBorderWidth(qRound(brd->getWidth())); |
19590 | jghali | 747 | } |
748 | else |
||
749 | { |
||
22748 | jghali | 750 | ite->annotation().setBorderStyle(0); |
19590 | jghali | 751 | ite->annotation().setBorderColor(CommonStrings::None); |
22748 | jghali | 752 | ite->annotation().setBorderWidth(0); |
19590 | jghali | 753 | } |
754 | QString tmTxt = ""; |
||
755 | tmTxt = UnicodeParsedString(fm->getPartialName()); |
||
756 | if (!tmTxt.isEmpty()) |
||
757 | ite->setItemName(tmTxt); |
||
758 | tmTxt = ""; |
||
759 | tmTxt = UnicodeParsedString(fm->getAlternateUiName()); |
||
760 | if (!tmTxt.isEmpty()) |
||
761 | ite->annotation().setToolTip(tmTxt); |
||
762 | tmTxt = ""; |
||
763 | if (achar) |
||
764 | { |
||
765 | tmTxt = UnicodeParsedString(achar->getRolloverCaption()); |
||
766 | if (!tmTxt.isEmpty()) |
||
767 | ite->annotation().setRollOver(tmTxt); |
||
768 | tmTxt = ""; |
||
769 | tmTxt = UnicodeParsedString(achar->getAlternateCaption()); |
||
770 | if (!tmTxt.isEmpty()) |
||
771 | ite->annotation().setDown(tmTxt); |
||
772 | } |
||
773 | ite->annotation().setType(wtyp); |
||
774 | ite->annotation().setFlag(0); |
||
775 | if (flg & 2) |
||
776 | ite->annotation().setVis(1); |
||
777 | if (flg & 32) |
||
778 | ite->annotation().setVis(3); |
||
779 | if (wtyp == Annotation::Button) |
||
780 | { |
||
781 | ite->setFillColor(CurrColorFill); |
||
782 | if (achar) |
||
783 | ite->itemText.insertChars(UnicodeParsedString(achar->getNormalCaption())); |
||
784 | else |
||
785 | ite->itemText.insertChars(itemText); |
||
786 | applyTextStyle(ite, fontName, CurrColorText, fontSize); |
||
787 | ite->annotation().addToFlag(Annotation::Flag_PushButton); |
||
788 | FormWidgetButton *btn = (FormWidgetButton*)fm; |
||
789 | if (!btn->isReadOnly()) |
||
790 | ite->annotation().addToFlag(Annotation::Flag_Edit); |
||
791 | handleActions(ite, ano); |
||
792 | } |
||
793 | else if (wtyp == Annotation::Textfield) |
||
794 | { |
||
795 | FormWidgetText *btn = (FormWidgetText*)fm; |
||
796 | if (btn) |
||
797 | { |
||
798 | ite->itemText.insertChars(UnicodeParsedString(btn->getContent())); |
||
799 | applyTextStyle(ite, fontName, CurrColorText, fontSize); |
||
800 | ite->itemText.trim(); |
||
801 | if (btn->isMultiline()) |
||
802 | ite->annotation().addToFlag(Annotation::Flag_Multiline); |
||
803 | if (btn->isPassword()) |
||
804 | ite->annotation().addToFlag(Annotation::Flag_Password); |
||
805 | if (btn->noSpellCheck()) |
||
806 | ite->annotation().addToFlag(Annotation::Flag_DoNotSpellCheck); |
||
807 | if (btn->noScroll()) |
||
808 | ite->annotation().addToFlag(Annotation::Flag_DoNotScroll); |
||
809 | int mxLen = btn->getMaxLen(); |
||
810 | if (mxLen > 0) |
||
811 | ite->annotation().setMaxChar(mxLen); |
||
812 | else |
||
813 | ite->annotation().setMaxChar(-1); |
||
814 | if (!btn->isReadOnly()) |
||
815 | ite->annotation().addToFlag(Annotation::Flag_Edit); |
||
816 | handleActions(ite, ano); |
||
817 | } |
||
818 | } |
||
819 | else if (wtyp == Annotation::Checkbox) |
||
820 | { |
||
821 | FormWidgetButton *btn = (FormWidgetButton*)fm; |
||
822 | if (btn) |
||
823 | { |
||
824 | ite->annotation().setIsChk(btn->getState()); |
||
825 | ite->annotation().setCheckState(ite->annotation().IsChk()); |
||
826 | handleActions(ite, ano); |
||
827 | if (itemText == "4") |
||
828 | ite->annotation().setChkStil(0); |
||
829 | else if (itemText == "5") |
||
830 | ite->annotation().setChkStil(1); |
||
831 | else if (itemText == "F") |
||
832 | ite->annotation().setChkStil(2); |
||
833 | else if (itemText == "l") |
||
834 | ite->annotation().setChkStil(3); |
||
835 | else if (itemText == "H") |
||
836 | ite->annotation().setChkStil(4); |
||
837 | else if (itemText == "n") |
||
838 | ite->annotation().setChkStil(5); |
||
839 | else |
||
840 | ite->annotation().setChkStil(0); |
||
841 | if (!btn->isReadOnly()) |
||
842 | ite->annotation().addToFlag(Annotation::Flag_Edit); |
||
843 | } |
||
844 | } |
||
845 | else if ((wtyp == Annotation::Combobox) || (wtyp == Annotation::Listbox)) |
||
846 | { |
||
847 | FormWidgetChoice *btn = (FormWidgetChoice*)fm; |
||
848 | if (btn) |
||
849 | { |
||
850 | if (wtyp == 5) |
||
851 | ite->annotation().addToFlag(Annotation::Flag_Combo); |
||
852 | int co = btn->getNumChoices(); |
||
853 | if (co > 0) |
||
854 | { |
||
855 | QString inh = UnicodeParsedString(btn->getChoice(0)); |
||
856 | for (int a = 1; a < co; a++) |
||
857 | { |
||
858 | inh += "\n" + UnicodeParsedString(btn->getChoice(a)); |
||
859 | } |
||
860 | ite->itemText.insertChars(inh); |
||
861 | } |
||
862 | applyTextStyle(ite, fontName, CurrColorText, fontSize); |
||
863 | if (!btn->isReadOnly()) |
||
864 | ite->annotation().addToFlag(Annotation::Flag_Edit); |
||
865 | handleActions(ite, ano); |
||
866 | } |
||
867 | } |
||
868 | else if (wtyp == Annotation::RadioButton) |
||
869 | { |
||
870 | FormWidgetButton *btn = (FormWidgetButton*)fm; |
||
871 | if (btn) |
||
872 | { |
||
873 | ite->setItemName( CommonStrings::itemName_RadioButton + QString("%1").arg(m_doc->TotalItems)); |
||
874 | ite->annotation().setIsChk(btn->getState()); |
||
875 | ite->annotation().setCheckState(ite->annotation().IsChk()); |
||
876 | handleActions(ite, ano); |
||
877 | m_radioButtons.insert(annota->getRef().num, ite); |
||
878 | } |
||
879 | } |
||
880 | } |
||
881 | break; |
||
882 | } |
||
883 | if (!found) |
||
884 | { |
||
885 | Object obj1; |
||
886 | Ref refa = annota->getRef(); |
||
22154 | jghali | 887 | obj1 = xref->fetch(refa.num, refa.gen); |
888 | if (obj1.isDict()) |
||
889 | { |
||
890 | Dict* dict = obj1.getDict(); |
||
891 | Object obj2 = dict->lookup("Kids"); |
||
892 | //childs |
||
893 | if (obj2.isArray()) |
||
894 | { |
||
895 | // Load children |
||
896 | QList<int> radList; |
||
897 | for (int i = 0; i < obj2.arrayGetLength(); i++) |
||
898 | { |
||
22906 | jghali | 899 | POPPLER_CONST_075 Object POPPLER_REF childRef = obj2.arrayGetNF(i); |
22154 | jghali | 900 | if (!childRef.isRef()) |
901 | continue; |
||
902 | Object childObj = obj2.arrayGet(i); |
||
903 | if (!childObj.isDict()) |
||
904 | continue; |
||
905 | const Ref ref = childRef.getRef(); |
||
906 | radList.append(ref.num); |
||
907 | } |
||
908 | QString tmTxt = UnicodeParsedString(annota->getName()); |
||
909 | m_radioMap.insert(tmTxt, radList); |
||
910 | } |
||
911 | } |
||
19590 | jghali | 912 | } |
913 | return retVal; |
||
914 | } |
||
915 | |||
22609 | craig | 916 | void SlaOutputDev::applyTextStyle(PageItem* ite, const QString& fontName, const QString& textColor, double fontSize) |
19590 | jghali | 917 | { |
918 | CharStyle newStyle; |
||
919 | newStyle.setFillColor(textColor); |
||
920 | newStyle.setFontSize(fontSize * 10); |
||
921 | if (!fontName.isEmpty()) |
||
922 | { |
||
923 | SCFontsIterator it(*m_doc->AllFonts); |
||
924 | for ( ; it.hasNext() ; it.next()) |
||
925 | { |
||
926 | ScFace& face(it.current()); |
||
927 | if ((face.psName() == fontName) && (face.usable()) && (face.type() == ScFace::TTF)) |
||
928 | { |
||
929 | newStyle.setFont(face); |
||
930 | break; |
||
931 | } |
||
22609 | craig | 932 | if ((face.family() == fontName) && (face.usable()) && (face.type() == ScFace::TTF)) |
19590 | jghali | 933 | { |
934 | newStyle.setFont(face); |
||
935 | break; |
||
936 | } |
||
22609 | craig | 937 | if ((face.scName() == fontName) && (face.usable()) && (face.type() == ScFace::TTF)) |
19590 | jghali | 938 | { |
939 | newStyle.setFont(face); |
||
940 | break; |
||
941 | } |
||
942 | } |
||
943 | } |
||
944 | ParagraphStyle dstyle(ite->itemText.defaultStyle()); |
||
945 | dstyle.charStyle().applyCharStyle(newStyle); |
||
946 | ite->itemText.setDefaultStyle(dstyle); |
||
947 | ite->itemText.applyCharStyle(0, ite->itemText.length(), newStyle); |
||
948 | ite->invalid = true; |
||
949 | } |
||
950 | |||
951 | void SlaOutputDev::handleActions(PageItem* ite, AnnotWidget *ano) |
||
952 | { |
||
953 | LinkAction *Lact = ano->getAction(); |
||
954 | if (Lact) |
||
955 | { |
||
956 | if (Lact->getKind() == actionJavaScript) |
||
957 | { |
||
958 | LinkJavaScript *jsa = (LinkJavaScript*)Lact; |
||
959 | if (jsa->isOk()) |
||
960 | { |
||
961 | ite->annotation().setActionType(1); |
||
962 | ite->annotation().setAction(UnicodeParsedString(jsa->getScript())); |
||
963 | } |
||
964 | } |
||
965 | else if (Lact->getKind() == actionGoTo) |
||
966 | { |
||
967 | int pagNum = 0; |
||
968 | int xco = 0; |
||
969 | int yco = 0; |
||
970 | LinkGoTo *gto = (LinkGoTo*)Lact; |
||
22513 | jghali | 971 | POPPLER_CONST LinkDest *dst = gto->getDest(); |
19590 | jghali | 972 | if (dst) |
973 | { |
||
974 | if (dst->getKind() == destXYZ) |
||
975 | { |
||
976 | if (dst->isPageRef()) |
||
977 | { |
||
978 | Ref dstr = dst->getPageRef(); |
||
22975 | jghali | 979 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 76, 0) |
980 | pagNum = pdfDoc->findPage(dstr); |
||
981 | #else |
||
19590 | jghali | 982 | pagNum = pdfDoc->findPage(dstr.num, dstr.gen); |
22975 | jghali | 983 | #endif |
19590 | jghali | 984 | } |
985 | else |
||
986 | pagNum = dst->getPageNum(); |
||
987 | xco = dst->getLeft(); |
||
988 | yco = dst->getTop(); |
||
21458 | jghali | 989 | ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1)); |
19590 | jghali | 990 | ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco)); |
991 | ite->annotation().setActionType(2); |
||
992 | } |
||
993 | } |
||
994 | else |
||
995 | { |
||
22513 | jghali | 996 | POPPLER_CONST GooString *ndst = gto->getNamedDest(); |
19590 | jghali | 997 | if (ndst) |
998 | { |
||
23478 | jghali | 999 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1000 | std::unique_ptr<LinkDest> dstn = pdfDoc->findDest(ndst); |
||
1001 | #else |
||
19590 | jghali | 1002 | LinkDest *dstn = pdfDoc->findDest(ndst); |
23478 | jghali | 1003 | #endif |
19590 | jghali | 1004 | if (dstn) |
1005 | { |
||
1006 | if (dstn->getKind() == destXYZ) |
||
1007 | { |
||
1008 | if (dstn->isPageRef()) |
||
1009 | { |
||
1010 | Ref dstr = dstn->getPageRef(); |
||
22975 | jghali | 1011 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 76, 0) |
1012 | pagNum = pdfDoc->findPage(dstr); |
||
1013 | #else |
||
19590 | jghali | 1014 | pagNum = pdfDoc->findPage(dstr.num, dstr.gen); |
22975 | jghali | 1015 | #endif |
19590 | jghali | 1016 | } |
1017 | else |
||
1018 | pagNum = dstn->getPageNum(); |
||
1019 | xco = dstn->getLeft(); |
||
1020 | yco = dstn->getTop(); |
||
21458 | jghali | 1021 | ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1)); |
19590 | jghali | 1022 | ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco)); |
1023 | ite->annotation().setActionType(2); |
||
1024 | } |
||
1025 | } |
||
1026 | } |
||
1027 | } |
||
1028 | } |
||
1029 | else if (Lact->getKind() == actionGoToR) |
||
1030 | { |
||
1031 | int pagNum = 0; |
||
1032 | int xco = 0; |
||
1033 | int yco = 0; |
||
1034 | LinkGoToR *gto = (LinkGoToR*)Lact; |
||
1035 | QString fileName = UnicodeParsedString(gto->getFileName()); |
||
22513 | jghali | 1036 | POPPLER_CONST LinkDest *dst = gto->getDest(); |
19590 | jghali | 1037 | if (dst) |
1038 | { |
||
1039 | if (dst->getKind() == destXYZ) |
||
1040 | { |
||
1041 | pagNum = dst->getPageNum(); |
||
1042 | xco = dst->getLeft(); |
||
1043 | yco = dst->getTop(); |
||
21458 | jghali | 1044 | ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1)); |
19590 | jghali | 1045 | ite->annotation().setExtern(fileName); |
1046 | ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco)); |
||
1047 | ite->annotation().setActionType(9); |
||
1048 | } |
||
1049 | } |
||
1050 | else |
||
1051 | { |
||
22513 | jghali | 1052 | POPPLER_CONST GooString *ndst = gto->getNamedDest(); |
19590 | jghali | 1053 | if (ndst) |
1054 | { |
||
23478 | jghali | 1055 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1056 | std::unique_ptr<LinkDest> dstn = pdfDoc->findDest(ndst); |
||
1057 | #else |
||
19590 | jghali | 1058 | LinkDest *dstn = pdfDoc->findDest(ndst); |
23478 | jghali | 1059 | #endif |
19590 | jghali | 1060 | if (dstn) |
1061 | { |
||
1062 | if (dstn->getKind() == destXYZ) |
||
1063 | { |
||
1064 | pagNum = dstn->getPageNum(); |
||
1065 | xco = dstn->getLeft(); |
||
1066 | yco = dstn->getTop(); |
||
21458 | jghali | 1067 | ite->annotation().setZiel((pagNum > 0) ? (pagNum - 1) : (m_actPage - 1)); |
19590 | jghali | 1068 | ite->annotation().setExtern(fileName); |
1069 | ite->annotation().setAction(QString("%1 %2").arg(xco).arg(yco)); |
||
1070 | ite->annotation().setActionType(9); |
||
1071 | } |
||
1072 | } |
||
1073 | } |
||
1074 | } |
||
1075 | } |
||
1076 | else if (Lact->getKind() == actionUnknown) |
||
1077 | { |
||
1078 | LinkUnknown *uno = (LinkUnknown*)Lact; |
||
1079 | QString actString = UnicodeParsedString(uno->getAction()); |
||
1080 | if (actString == "ResetForm") |
||
1081 | { |
||
1082 | ite->annotation().setActionType(4); |
||
1083 | } |
||
1084 | else |
||
1085 | { |
||
1086 | LinkAction* scact = SC_getAction(ano); |
||
1087 | if (scact) |
||
1088 | { |
||
1089 | if (actString == "ImportData") |
||
1090 | { |
||
1091 | LinkImportData *impo = (LinkImportData*)scact; |
||
1092 | if (impo->isOk()) |
||
1093 | { |
||
1094 | ite->annotation().setActionType(5); |
||
1095 | ite->annotation().setAction(UnicodeParsedString(impo->getFileName())); |
||
1096 | } |
||
1097 | } |
||
1098 | else if (actString == "SubmitForm") |
||
1099 | { |
||
1100 | LinkSubmitForm *impo = (LinkSubmitForm*)scact; |
||
1101 | if (impo->isOk()) |
||
1102 | { |
||
1103 | ite->annotation().setActionType(3); |
||
1104 | ite->annotation().setAction(UnicodeParsedString(impo->getFileName())); |
||
1105 | int fl = impo->getFlags(); |
||
1106 | if (fl == 0) |
||
1107 | ite->annotation().setHTML(0); |
||
1108 | else if (fl == 4) |
||
1109 | ite->annotation().setHTML(1); |
||
1110 | else if (fl == 64) |
||
1111 | ite->annotation().setHTML(2); |
||
1112 | else if (fl == 512) |
||
1113 | ite->annotation().setHTML(3); |
||
1114 | } |
||
1115 | } |
||
1116 | } |
||
1117 | } |
||
1118 | } |
||
1119 | else if (Lact->getKind() == actionNamed) |
||
1120 | { |
||
1121 | LinkNamed *uno = (LinkNamed*)Lact; |
||
1122 | ite->annotation().setActionType(10); |
||
1123 | ite->annotation().setAction(UnicodeParsedString(uno->getName())); |
||
1124 | } |
||
1125 | else |
||
1126 | qDebug() << "Found unsupported Action of type" << Lact->getKind(); |
||
1127 | } |
||
23478 | jghali | 1128 | auto Aact = SC_getAdditionalAction("D", ano); |
19590 | jghali | 1129 | if (Aact) |
1130 | { |
||
1131 | if (Aact->getKind() == actionJavaScript) |
||
1132 | { |
||
23478 | jghali | 1133 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1134 | LinkJavaScript *jsa = (LinkJavaScript*) Aact.get(); |
||
1135 | #else |
||
1136 | LinkJavaScript *jsa = (LinkJavaScript*) Aact; |
||
1137 | #endif |
||
19590 | jghali | 1138 | if (jsa->isOk()) |
1139 | { |
||
1140 | ite->annotation().setD_act(UnicodeParsedString(jsa->getScript())); |
||
1141 | ite->annotation().setAAact(true); |
||
1142 | } |
||
1143 | } |
||
23478 | jghali | 1144 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1145 | Aact.reset(); |
||
1146 | #else |
||
22527 | craig | 1147 | Aact = nullptr; |
23478 | jghali | 1148 | #endif |
19590 | jghali | 1149 | } |
1150 | Aact = SC_getAdditionalAction("E", ano); |
||
1151 | if (Aact) |
||
1152 | { |
||
1153 | if (Aact->getKind() == actionJavaScript) |
||
1154 | { |
||
23478 | jghali | 1155 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1156 | LinkJavaScript *jsa = (LinkJavaScript*) Aact.get(); |
||
1157 | #else |
||
1158 | LinkJavaScript *jsa = (LinkJavaScript*) Aact; |
||
1159 | #endif |
||
19590 | jghali | 1160 | if (jsa->isOk()) |
1161 | { |
||
1162 | ite->annotation().setE_act(UnicodeParsedString(jsa->getScript())); |
||
1163 | ite->annotation().setAAact(true); |
||
1164 | } |
||
1165 | } |
||
23478 | jghali | 1166 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1167 | Aact.reset(); |
||
1168 | #else |
||
22527 | craig | 1169 | Aact = nullptr; |
23478 | jghali | 1170 | #endif |
19590 | jghali | 1171 | } |
1172 | Aact = SC_getAdditionalAction("X", ano); |
||
1173 | if (Aact) |
||
1174 | { |
||
1175 | if (Aact->getKind() == actionJavaScript) |
||
1176 | { |
||
23478 | jghali | 1177 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1178 | LinkJavaScript *jsa = (LinkJavaScript*) Aact.get(); |
||
1179 | #else |
||
1180 | LinkJavaScript *jsa = (LinkJavaScript*) Aact; |
||
1181 | #endif |
||
19590 | jghali | 1182 | if (jsa->isOk()) |
1183 | { |
||
1184 | ite->annotation().setX_act(UnicodeParsedString(jsa->getScript())); |
||
1185 | ite->annotation().setAAact(true); |
||
1186 | } |
||
1187 | } |
||
23478 | jghali | 1188 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1189 | Aact.reset(); |
||
1190 | #else |
||
22527 | craig | 1191 | Aact = nullptr; |
23478 | jghali | 1192 | #endif |
19590 | jghali | 1193 | } |
1194 | Aact = SC_getAdditionalAction("Fo", ano); |
||
1195 | if (Aact) |
||
1196 | { |
||
1197 | if (Aact->getKind() == actionJavaScript) |
||
1198 | { |
||
23478 | jghali | 1199 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1200 | LinkJavaScript *jsa = (LinkJavaScript*) Aact.get(); |
||
1201 | #else |
||
1202 | LinkJavaScript *jsa = (LinkJavaScript*) Aact; |
||
1203 | #endif |
||
19590 | jghali | 1204 | if (jsa->isOk()) |
1205 | { |
||
1206 | ite->annotation().setFo_act(UnicodeParsedString(jsa->getScript())); |
||
1207 | ite->annotation().setAAact(true); |
||
1208 | } |
||
1209 | } |
||
23478 | jghali | 1210 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1211 | Aact.reset(); |
||
1212 | #else |
||
22527 | craig | 1213 | Aact = nullptr; |
23478 | jghali | 1214 | #endif |
19590 | jghali | 1215 | } |
1216 | Aact = SC_getAdditionalAction("Bl", ano); |
||
1217 | if (Aact) |
||
1218 | { |
||
1219 | if (Aact->getKind() == actionJavaScript) |
||
1220 | { |
||
23478 | jghali | 1221 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1222 | LinkJavaScript *jsa = (LinkJavaScript*) Aact.get(); |
||
1223 | #else |
||
1224 | LinkJavaScript *jsa = (LinkJavaScript*) Aact; |
||
1225 | #endif |
||
19590 | jghali | 1226 | if (jsa->isOk()) |
1227 | { |
||
1228 | ite->annotation().setBl_act(UnicodeParsedString(jsa->getScript())); |
||
1229 | ite->annotation().setAAact(true); |
||
1230 | } |
||
1231 | } |
||
23478 | jghali | 1232 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1233 | Aact.reset(); |
||
1234 | #else |
||
22527 | craig | 1235 | Aact = nullptr; |
23478 | jghali | 1236 | #endif |
19590 | jghali | 1237 | } |
1238 | Aact = SC_getAdditionalAction("C", ano); |
||
1239 | if (Aact) |
||
1240 | { |
||
1241 | if (Aact->getKind() == actionJavaScript) |
||
1242 | { |
||
23478 | jghali | 1243 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1244 | LinkJavaScript *jsa = (LinkJavaScript*) Aact.get(); |
||
1245 | #else |
||
1246 | LinkJavaScript *jsa = (LinkJavaScript*) Aact; |
||
1247 | #endif |
||
19590 | jghali | 1248 | if (jsa->isOk()) |
1249 | { |
||
1250 | ite->annotation().setC_act(UnicodeParsedString(jsa->getScript())); |
||
1251 | ite->annotation().setAAact(true); |
||
1252 | } |
||
1253 | } |
||
23478 | jghali | 1254 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1255 | Aact.reset(); |
||
1256 | #else |
||
22527 | craig | 1257 | Aact = nullptr; |
23478 | jghali | 1258 | #endif |
19590 | jghali | 1259 | } |
1260 | Aact = SC_getAdditionalAction("F", ano); |
||
1261 | if (Aact) |
||
1262 | { |
||
1263 | if (Aact->getKind() == actionJavaScript) |
||
1264 | { |
||
23478 | jghali | 1265 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1266 | LinkJavaScript *jsa = (LinkJavaScript*) Aact.get(); |
||
1267 | #else |
||
1268 | LinkJavaScript *jsa = (LinkJavaScript*) Aact; |
||
1269 | #endif |
||
19590 | jghali | 1270 | if (jsa->isOk()) |
1271 | { |
||
1272 | ite->annotation().setF_act(UnicodeParsedString(jsa->getScript())); |
||
1273 | ite->annotation().setAAact(true); |
||
1274 | ite->annotation().setFormat(5); |
||
1275 | } |
||
1276 | } |
||
23478 | jghali | 1277 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1278 | Aact.reset(); |
||
1279 | #else |
||
22527 | craig | 1280 | Aact = nullptr; |
23478 | jghali | 1281 | #endif |
19590 | jghali | 1282 | } |
1283 | Aact = SC_getAdditionalAction("K", ano); |
||
1284 | if (Aact) |
||
1285 | { |
||
1286 | if (Aact->getKind() == actionJavaScript) |
||
1287 | { |
||
23478 | jghali | 1288 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1289 | LinkJavaScript *jsa = (LinkJavaScript*) Aact.get(); |
||
1290 | #else |
||
1291 | LinkJavaScript *jsa = (LinkJavaScript*) Aact; |
||
1292 | #endif |
||
19590 | jghali | 1293 | if (jsa->isOk()) |
1294 | { |
||
1295 | ite->annotation().setK_act(UnicodeParsedString(jsa->getScript())); |
||
1296 | ite->annotation().setAAact(true); |
||
1297 | ite->annotation().setFormat(5); |
||
1298 | } |
||
1299 | } |
||
23478 | jghali | 1300 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1301 | Aact.reset(); |
||
1302 | #else |
||
22527 | craig | 1303 | Aact = nullptr; |
23478 | jghali | 1304 | #endif |
19590 | jghali | 1305 | } |
1306 | Aact = SC_getAdditionalAction("V", ano); |
||
1307 | if (Aact) |
||
1308 | { |
||
1309 | if (Aact->getKind() == actionJavaScript) |
||
1310 | { |
||
23478 | jghali | 1311 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1312 | LinkJavaScript *jsa = (LinkJavaScript*) Aact.get(); |
||
1313 | #else |
||
1314 | LinkJavaScript *jsa = (LinkJavaScript*) Aact; |
||
1315 | #endif |
||
19590 | jghali | 1316 | if (jsa->isOk()) |
1317 | { |
||
1318 | ite->annotation().setV_act(UnicodeParsedString(jsa->getScript())); |
||
1319 | ite->annotation().setAAact(true); |
||
1320 | } |
||
1321 | } |
||
23478 | jghali | 1322 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 86, 0) |
1323 | Aact.reset(); |
||
1324 | #else |
||
22527 | craig | 1325 | Aact = nullptr; |
23478 | jghali | 1326 | #endif |
19590 | jghali | 1327 | } |
1328 | } |
||
1329 | |||
1330 | void SlaOutputDev::startDoc(PDFDoc *doc, XRef *xrefA, Catalog *catA) |
||
1331 | { |
||
1332 | xref = xrefA; |
||
1333 | catalog = catA; |
||
1334 | pdfDoc = doc; |
||
1335 | updateGUICounter = 0; |
||
23429 | jghali | 1336 | #if POPPLER_ENCODED_VERSION >= POPPLER_VERSION_ENCODE(0, 84, 0) |
23431 | jghali | 1337 | m_fontEngine = new SplashFontEngine(true, false, false, true); |
23479 | jghali | 1338 | #else |
23431 | jghali | 1339 | m_fontEngine = new SplashFontEngine(globalParams->getEnableFreeType(), false, false, true); |
19590 | jghali | 1340 | #endif |
1341 | } |
||
1342 | |||
19595 | jghali | 1343 | void SlaOutputDev::startPage(int pageNum, GfxState *, XRef *) |
19590 | jghali | 1344 | { |
1345 | m_formWidgets = pdfDoc->getPage(pageNum)->getFormWidgets(); |
||
1346 | m_radioMap.clear(); |
||
1347 | m_radioButtons.clear(); |
||
1348 | m_actPage = pageNum; |
||
20011 | fschmid | 1349 | m_groupStack.clear(); |
1350 | pushGroup(); |
||
23536 | jghali | 1351 | m_currentClipPath = QPainterPath(); |
20011 | fschmid | 1352 | m_clipPaths.clear(); |
19590 | jghali | 1353 | } |
1354 | |||
1355 | void SlaOutputDev::endPage() |
||
1356 | { |
||
1357 | if (!m_radioMap.isEmpty()) |
||
1358 | { |
||
22509 | jghali | 1359 | for (auto it = m_radioMap.begin(); it != m_radioMap.end(); ++it) |
19590 | jghali | 1360 | { |
1361 | tmpSel->clear(); |
||
1362 | QList<int> refList = it.value(); |
||
1363 | for (int a = 0; a < refList.count(); a++) |
||
1364 | { |
||
1365 | if (m_radioButtons.contains(refList[a])) |
||
1366 | { |
||
1367 | tmpSel->addItem(m_radioButtons[refList[a]], true); |
||
1368 | m_Elements->removeAll(m_radioButtons[refList[a]]); |
||
1369 | } |
||
1370 | } |
||
1371 | if (!tmpSel->isEmpty()) |
||
1372 | { |
||
1373 | PageItem *ite = m_doc->groupObjectsSelection(tmpSel); |
||
1374 | ite->setItemName(it.key()); |
||
1375 | m_Elements->append(ite); |
||
1376 | if (m_groupStack.count() != 0) |
||
1377 | m_groupStack.top().Items.append(ite); |
||
1378 | } |
||
1379 | } |
||
1380 | } |
||
1381 | m_radioMap.clear(); |
||
1382 | m_radioButtons.clear(); |
||
1383 | // qDebug() << "ending page"; |
||
1384 | } |
||
1385 | |||
1386 | void SlaOutputDev::saveState(GfxState *state) |
||
1387 | { |
||
20011 | fschmid | 1388 | m_clipPaths.push(m_currentClipPath); |
1389 | pushGroup(); |
||
19590 | jghali | 1390 | } |
1391 | |||
1392 | void SlaOutputDev::restoreState(GfxState *state) |
||
1393 | { |
||
1394 | if (m_groupStack.count() != 0) |
||
1395 | { |
||
20011 | fschmid | 1396 | groupEntry gElements = m_groupStack.pop(); |
1397 | if (gElements.Items.count() > 0) |
||
19590 | jghali | 1398 | { |
20625 | fschmid | 1399 | if ((gElements.Items.count() > 1) && (checkClip())) |
19590 | jghali | 1400 | { |
20011 | fschmid | 1401 | tmpSel->clear(); |
1402 | for (int dre = 0; dre < gElements.Items.count(); ++dre) |
||
19590 | jghali | 1403 | { |
20011 | fschmid | 1404 | tmpSel->addItem(gElements.Items.at(dre), true); |
1405 | m_Elements->removeAll(gElements.Items.at(dre)); |
||
19590 | jghali | 1406 | } |
20011 | fschmid | 1407 | PageItem *ite = m_doc->groupObjectsSelection(tmpSel); |
20625 | fschmid | 1408 | if (ite) |
19590 | jghali | 1409 | { |
23536 | jghali | 1410 | QPainterPath clippath = m_currentClipPath; |
1411 | clippath.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset()); |
||
1412 | clippath.translate(-ite->xPos(), -ite->yPos()); |
||
1413 | ite->PoLine.fromQPainterPath(clippath, true); |
||
23319 | jghali | 1414 | ite->ClipEdited = true; |
1415 | ite->FrameType = 3; |
||
20625 | fschmid | 1416 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
23319 | jghali | 1417 | // Comment out temporarily, there are some bad interactions between adjustItemSize() and |
1418 | // resizeGroupToContents() since fixing resizing of multiple selections |
||
1419 | //m_doc->adjustItemSize(ite, true); |
||
20625 | fschmid | 1420 | m_doc->resizeGroupToContents(ite); |
1421 | ite->OldB2 = ite->width(); |
||
1422 | ite->OldH2 = ite->height(); |
||
1423 | m_Elements->append(ite); |
||
1424 | if (m_groupStack.count() != 0) |
||
1425 | { |
||
1426 | applyMask(ite); |
||
1427 | m_groupStack.top().Items.append(ite); |
||
1428 | } |
||
19590 | jghali | 1429 | } |
20628 | fschmid | 1430 | else |
1431 | { |
||
1432 | if (m_groupStack.count() != 0) |
||
1433 | { |
||
1434 | for (int dre = 0; dre < gElements.Items.count(); ++dre) |
||
1435 | { |
||
1436 | PageItem *ite = gElements.Items.at(dre); |
||
1437 | applyMask(ite); |
||
1438 | m_groupStack.top().Items.append(ite); |
||
1439 | } |
||
1440 | } |
||
1441 | } |
||
20011 | fschmid | 1442 | tmpSel->clear(); |
19590 | jghali | 1443 | } |
20011 | fschmid | 1444 | else |
1445 | { |
||
1446 | if (m_groupStack.count() != 0) |
||
1447 | { |
||
1448 | for (int dre = 0; dre < gElements.Items.count(); ++dre) |
||
1449 | { |
||
1450 | PageItem *ite = gElements.Items.at(dre); |
||
1451 | applyMask(ite); |
||
1452 | m_groupStack.top().Items.append(ite); |
||
1453 | } |
||
1454 | } |
||
1455 | } |
||
19590 | jghali | 1456 | } |
1457 | } |
||
20011 | fschmid | 1458 | if (m_clipPaths.count() != 0) |
1459 | m_currentClipPath = m_clipPaths.pop(); |
||
19590 | jghali | 1460 | } |
20011 | fschmid | 1461 | |
22916 | jghali | 1462 | void SlaOutputDev::beginTransparencyGroup(GfxState *state, POPPLER_CONST_070 double *bbox, GfxColorSpace * /*blendingColorSpace*/, GBool isolated, GBool knockout, GBool forSoftMask) |
19590 | jghali | 1463 | { |
23550 | jghali | 1464 | // qDebug() << "SlaOutputDev::beginTransparencyGroup isolated:" << isolated << "knockout:" << knockout << "forSoftMask:" << forSoftMask; |
20011 | fschmid | 1465 | pushGroup("", forSoftMask); |
20125 | fschmid | 1466 | m_groupStack.top().isolated = isolated; |
19590 | jghali | 1467 | } |
20011 | fschmid | 1468 | |
22916 | jghali | 1469 | void SlaOutputDev::paintTransparencyGroup(GfxState *state, POPPLER_CONST_070 double *bbox) |
19590 | jghali | 1470 | { |
23550 | jghali | 1471 | // qDebug() << "SlaOutputDev::paintTransparencyGroup"; |
20011 | fschmid | 1472 | if (m_groupStack.count() != 0) |
1473 | { |
||
1474 | if ((m_groupStack.top().Items.count() != 0) && (!m_groupStack.top().forSoftMask)) |
||
1475 | { |
||
1476 | PageItem *ite = m_groupStack.top().Items.last(); |
||
1477 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
1478 | ite->setFillBlendmode(getBlendMode(state)); |
||
1479 | } |
||
1480 | } |
||
19590 | jghali | 1481 | } |
1482 | |||
1483 | void SlaOutputDev::endTransparencyGroup(GfxState *state) |
||
1484 | { |
||
23550 | jghali | 1485 | // qDebug() << "SlaOutputDev::endTransparencyGroup"; |
22991 | jghali | 1486 | if (m_groupStack.count() <= 0) |
1487 | return; |
||
1488 | |||
1489 | tmpSel->clear(); |
||
1490 | |||
1491 | groupEntry gElements = m_groupStack.pop(); |
||
1492 | if (gElements.Items.count() <= 0) |
||
1493 | return; |
||
1494 | |||
1495 | if (gElements.forSoftMask) |
||
19590 | jghali | 1496 | { |
22991 | jghali | 1497 | for (int dre = 0; dre < gElements.Items.count(); ++dre) |
19590 | jghali | 1498 | { |
22991 | jghali | 1499 | tmpSel->addItem(gElements.Items.at(dre), true); |
1500 | m_Elements->removeAll(gElements.Items.at(dre)); |
||
19590 | jghali | 1501 | } |
22991 | jghali | 1502 | PageItem *ite = m_doc->groupObjectsSelection(tmpSel); |
1503 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
1504 | ite->setFillBlendmode(getBlendMode(state)); |
||
1505 | ScPattern pat = ScPattern(); |
||
1506 | pat.setDoc(m_doc); |
||
1507 | m_doc->DoDrawing = true; |
||
1508 | pat.pattern = ite->DrawObj_toImage(qMin(qMax(ite->width(), ite->height()), 500.0)); |
||
1509 | pat.xoffset = 0; |
||
1510 | pat.yoffset = 0; |
||
1511 | m_doc->DoDrawing = false; |
||
1512 | pat.width = ite->width(); |
||
1513 | pat.height = ite->height(); |
||
23550 | jghali | 1514 | m_currentMaskPosition = QPointF(ite->xPos(), ite->yPos()); |
22991 | jghali | 1515 | ite->gXpos = 0; |
1516 | ite->gYpos = 0; |
||
1517 | ite->setXYPos(ite->gXpos, ite->gYpos, true); |
||
1518 | pat.items.append(ite); |
||
1519 | m_doc->Items->removeAll(ite); |
||
1520 | QString id = QString("Pattern_from_PDF_%1S").arg(m_doc->docPatterns.count() + 1); |
||
1521 | m_doc->addPattern(id, pat); |
||
1522 | m_currentMask = id; |
||
19590 | jghali | 1523 | tmpSel->clear(); |
22991 | jghali | 1524 | return; |
19590 | jghali | 1525 | } |
22991 | jghali | 1526 | PageItem *ite; |
1527 | for (int dre = 0; dre < gElements.Items.count(); ++dre) |
||
1528 | { |
||
1529 | tmpSel->addItem(gElements.Items.at(dre), true); |
||
1530 | m_Elements->removeAll(gElements.Items.at(dre)); |
||
1531 | } |
||
1532 | if ((gElements.Items.count() != 1) || (gElements.isolated)) |
||
1533 | ite = m_doc->groupObjectsSelection(tmpSel); |
||
1534 | else |
||
1535 | ite = gElements.Items.first(); |
||
1536 | if (ite->isGroup()) |
||
1537 | { |
||
1538 | ite->ClipEdited = true; |
||
1539 | ite->FrameType = 3; |
||
1540 | if (checkClip()) |
||
1541 | { |
||
23536 | jghali | 1542 | QPainterPath clippath = m_currentClipPath; |
1543 | clippath.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset()); |
||
1544 | clippath.translate(-ite->xPos(), -ite->yPos()); |
||
1545 | ite->PoLine.fromQPainterPath(clippath, true); |
||
23319 | jghali | 1546 | ite->ClipEdited = true; |
1547 | ite->FrameType = 3; |
||
22991 | jghali | 1548 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
23319 | jghali | 1549 | // Comment out temporarily, there are some bad interactions between adjustItemSize() and |
1550 | // resizeGroupToContents() since fixing resizing of multiple selections |
||
1551 | //m_doc->adjustItemSize(ite, true); |
||
22991 | jghali | 1552 | m_doc->resizeGroupToContents(ite); |
1553 | ite->OldB2 = ite->width(); |
||
1554 | ite->OldH2 = ite->height(); |
||
1555 | } |
||
1556 | } |
||
1557 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
1558 | ite->setFillBlendmode(getBlendMode(state)); |
||
1559 | m_Elements->append(ite); |
||
1560 | if (m_groupStack.count() != 0) |
||
1561 | { |
||
1562 | applyMask(ite); |
||
1563 | m_groupStack.top().Items.append(ite); |
||
1564 | } |
||
1565 | |||
1566 | tmpSel->clear(); |
||
19590 | jghali | 1567 | } |
1568 | |||
23525 | jghali | 1569 | void SlaOutputDev::setSoftMask(GfxState * /*state*/, POPPLER_CONST_070 double * bbox, GBool alpha, Function *transferFunc, GfxColor * /*backdropColor*/) |
19590 | jghali | 1570 | { |
22991 | jghali | 1571 | if (m_groupStack.count() <= 0) |
1572 | return; |
||
1573 | |||
1574 | double lum = 0; |
||
1575 | double lum2 = 0; |
||
1576 | if (transferFunc) |
||
1577 | transferFunc->transform(&lum, &lum2); |
||
1578 | else |
||
1579 | lum2 = lum; |
||
1580 | if (lum == lum2) |
||
1581 | m_groupStack.top().inverted = false; |
||
1582 | else |
||
1583 | m_groupStack.top().inverted = true; |
||
1584 | m_groupStack.top().maskName = m_currentMask; |
||
23550 | jghali | 1585 | // Remember the mask's position as it might not align with the image to which the mask is later assigned. |
1586 | m_groupStack.top().maskPos = m_currentMaskPosition; |
||
22991 | jghali | 1587 | m_groupStack.top().alpha = alpha; |
1588 | if (m_groupStack.top().Items.count() != 0) |
||
1589 | applyMask(m_groupStack.top().Items.last()); |
||
19590 | jghali | 1590 | } |
1591 | |||
1592 | void SlaOutputDev::clearSoftMask(GfxState * /*state*/) |
||
1593 | { |
||
1594 | if (m_groupStack.count() != 0) |
||
1595 | m_groupStack.top().maskName = ""; |
||
1596 | } |
||
1597 | |||
1598 | void SlaOutputDev::updateFillColor(GfxState *state) |
||
1599 | { |
||
1600 | CurrFillShade = 100; |
||
1601 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &CurrFillShade); |
||
1602 | } |
||
1603 | |||
1604 | void SlaOutputDev::updateStrokeColor(GfxState *state) |
||
1605 | { |
||
1606 | CurrStrokeShade = 100; |
||
1607 | CurrColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &CurrStrokeShade); |
||
1608 | } |
||
1609 | |||
1610 | void SlaOutputDev::clip(GfxState *state) |
||
1611 | { |
||
1612 | // qDebug() << "Clip"; |
||
23536 | jghali | 1613 | adjustClip(state, Qt::WindingFill); |
1614 | } |
||
1615 | |||
1616 | void SlaOutputDev::eoClip(GfxState *state) |
||
1617 | { |
||
1618 | // qDebug() << "EoClip"; |
||
1619 | adjustClip(state, Qt::OddEvenFill); |
||
1620 | } |
||
1621 | |||
1622 | void SlaOutputDev::adjustClip(GfxState *state, Qt::FillRule fillRule) |
||
1623 | { |
||
1624 | const double *ctm = state->getCTM(); |
||
19590 | jghali | 1625 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
1626 | QString output = convertPath(state->getPath()); |
||
22991 | jghali | 1627 | if (output.isEmpty()) |
1628 | return; |
||
19590 | jghali | 1629 | FPointArray out; |
22991 | jghali | 1630 | out.parseSVG(output); |
1631 | out.svgClosePath(); |
||
1632 | out.map(m_ctm); |
||
1633 | if (checkClip()) |
||
19590 | jghali | 1634 | { |
23536 | jghali | 1635 | // "clip" (WindingFill) and "eoClip" (OddEvenFill) only the determine |
1636 | // the fill rule of the new clipping path. The new clip should be the |
||
1637 | // intersection of the old and new area. QPainterPath determines on |
||
1638 | // its own which fill rule to use for the result. We should not loose |
||
1639 | // this information. |
||
1640 | QPainterPath pathN = out.toQPainterPath(false); |
||
1641 | pathN.setFillRule(fillRule); |
||
23550 | jghali | 1642 | m_currentClipPath = intersection(pathN, m_currentClipPath); |
19590 | jghali | 1643 | } |
22991 | jghali | 1644 | else |
23536 | jghali | 1645 | m_currentClipPath = out.toQPainterPath(false); |
19590 | jghali | 1646 | } |
1647 | |||
1648 | void SlaOutputDev::stroke(GfxState *state) |
||
1649 | { |
||
1650 | // qDebug() << "Stroke"; |
||
22741 | jghali | 1651 | const double *ctm; |
19590 | jghali | 1652 | ctm = state->getCTM(); |
1653 | double xCoor = m_doc->currentPage()->xOffset(); |
||
1654 | double yCoor = m_doc->currentPage()->yOffset(); |
||
1655 | QString output = convertPath(state->getPath()); |
||
1656 | getPenState(state); |
||
1657 | if ((m_Elements->count() != 0) && (output == Coords)) // Path is the same as in last fill |
||
1658 | { |
||
1659 | PageItem* ite = m_Elements->last(); |
||
1660 | ite->setLineColor(CurrColorStroke); |
||
1661 | ite->setLineShade(CurrStrokeShade); |
||
1662 | ite->setLineEnd(PLineEnd); |
||
1663 | ite->setLineJoin(PLineJoin); |
||
1664 | ite->setLineWidth(state->getTransformedLineWidth()); |
||
1665 | ite->setDashes(DashValues); |
||
1666 | ite->setDashOffset(DashOffset); |
||
1667 | ite->setLineTransparency(1.0 - state->getStrokeOpacity()); |
||
1668 | } |
||
1669 | else |
||
1670 | { |
||
1671 | FPointArray out; |
||
1672 | out.parseSVG(output); |
||
1673 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
1674 | out.map(m_ctm); |
||
23038 | jghali | 1675 | FPoint wh = out.widthHeight(); |
19590 | jghali | 1676 | if ((out.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0))) |
1677 | { |
||
19731 | fschmid | 1678 | CurrColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &CurrStrokeShade); |
19590 | jghali | 1679 | int z; |
1680 | if (pathIsClosed) |
||
20561 | jghali | 1681 | z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, state->getTransformedLineWidth(), CommonStrings::None, CurrColorStroke); |
19590 | jghali | 1682 | else |
20561 | jghali | 1683 | z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, state->getTransformedLineWidth(), CommonStrings::None, CurrColorStroke); |
19590 | jghali | 1684 | PageItem* ite = m_doc->Items->at(z); |
1685 | ite->PoLine = out.copy(); |
||
1686 | ite->ClipEdited = true; |
||
1687 | ite->FrameType = 3; |
||
23289 | jghali | 1688 | ite->setWidthHeight(wh.x(), wh.y()); |
20694 | craig | 1689 | m_doc->adjustItemSize(ite); |
19590 | jghali | 1690 | if (m_Elements->count() != 0) |
1691 | { |
||
1692 | PageItem* lItem = m_Elements->last(); |
||
1693 | if ((lItem->lineColor() == CommonStrings::None) && (lItem->PoLine == ite->PoLine)) |
||
1694 | { |
||
1695 | lItem->setLineColor(CurrColorStroke); |
||
1696 | lItem->setLineWidth(state->getTransformedLineWidth()); |
||
1697 | lItem->setLineShade(CurrStrokeShade); |
||
1698 | lItem->setLineTransparency(1.0 - state->getStrokeOpacity()); |
||
1699 | lItem->setLineBlendmode(getBlendMode(state)); |
||
1700 | lItem->setLineEnd(PLineEnd); |
||
1701 | lItem->setLineJoin(PLineJoin); |
||
1702 | lItem->setDashes(DashValues); |
||
1703 | lItem->setDashOffset(DashOffset); |
||
1704 | lItem->setTextFlowMode(PageItem::TextFlowDisabled); |
||
1705 | m_doc->Items->removeAll(ite); |
||
1706 | } |
||
1707 | else |
||
1708 | { |
||
1709 | ite->setLineShade(CurrStrokeShade); |
||
1710 | ite->setLineTransparency(1.0 - state->getStrokeOpacity()); |
||
1711 | ite->setLineBlendmode(getBlendMode(state)); |
||
1712 | ite->setLineEnd(PLineEnd); |
||
1713 | ite->setLineJoin(PLineJoin); |
||
1714 | ite->setDashes(DashValues); |
||
1715 | ite->setDashOffset(DashOffset); |
||
1716 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
1717 | m_Elements->append(ite); |
||
1718 | if (m_groupStack.count() != 0) |
||
1719 | m_groupStack.top().Items.append(ite); |
||
1720 | } |
||
1721 | } |
||
1722 | else |
||
1723 | { |
||
1724 | ite->setLineShade(CurrStrokeShade); |
||
1725 | ite->setLineTransparency(1.0 - state->getStrokeOpacity()); |
||
1726 | ite->setLineBlendmode(getBlendMode(state)); |
||
1727 | ite->setLineEnd(PLineEnd); |
||
1728 | ite->setLineJoin(PLineJoin); |
||
1729 | ite->setDashes(DashValues); |
||
1730 | ite->setDashOffset(DashOffset); |
||
1731 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
1732 | m_Elements->append(ite); |
||
1733 | if (m_groupStack.count() != 0) |
||
1734 | m_groupStack.top().Items.append(ite); |
||
1735 | } |
||
1736 | } |
||
1737 | } |
||
1738 | } |
||
1739 | |||
1740 | void SlaOutputDev::fill(GfxState *state) |
||
1741 | { |
||
1742 | // qDebug() << "Fill"; |
||
23536 | jghali | 1743 | createFillItem(state, Qt::WindingFill); |
19590 | jghali | 1744 | } |
1745 | |||
1746 | void SlaOutputDev::eoFill(GfxState *state) |
||
1747 | { |
||
1748 | // qDebug() << "EoFill"; |
||
23536 | jghali | 1749 | createFillItem(state, Qt::OddEvenFill); |
1750 | } |
||
1751 | |||
1752 | void SlaOutputDev::createFillItem(GfxState *state, Qt::FillRule fillRule) |
||
1753 | { |
||
22741 | jghali | 1754 | const double *ctm; |
19590 | jghali | 1755 | ctm = state->getCTM(); |
23550 | jghali | 1756 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
19590 | jghali | 1757 | double xCoor = m_doc->currentPage()->xOffset(); |
1758 | double yCoor = m_doc->currentPage()->yOffset(); |
||
1759 | FPointArray out; |
||
1760 | QString output = convertPath(state->getPath()); |
||
1761 | out.parseSVG(output); |
||
1762 | out.map(m_ctm); |
||
23536 | jghali | 1763 | |
1764 | // Clip the new path first and only add it if it is not empty. |
||
1765 | QPainterPath path = out.toQPainterPath(false); |
||
1766 | path.setFillRule(fillRule); |
||
23550 | jghali | 1767 | QPainterPath clippedPath = intersection(m_currentClipPath, path); |
23536 | jghali | 1768 | |
23550 | jghali | 1769 | // Undo the rotation of the clipping path as it is rotated together with the item. |
1770 | double angle = m_ctm.map(QLineF(0, 0, 1, 0)).angle(); |
||
1771 | QTransform mm; |
||
1772 | mm.rotate(angle); |
||
1773 | clippedPath = mm.map(clippedPath); |
||
1774 | |||
19590 | jghali | 1775 | Coords = output; |
23536 | jghali | 1776 | QRectF bbox = clippedPath.boundingRect(); |
1777 | if (!clippedPath.isEmpty() && !bbox.isNull()) |
||
19590 | jghali | 1778 | { |
20628 | fschmid | 1779 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &CurrFillShade); |
19590 | jghali | 1780 | int z; |
1781 | if (pathIsClosed) |
||
20561 | jghali | 1782 | z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CurrColorFill, CommonStrings::None); |
19590 | jghali | 1783 | else |
20561 | jghali | 1784 | z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CurrColorFill, CommonStrings::None); |
19590 | jghali | 1785 | PageItem* ite = m_doc->Items->at(z); |
23536 | jghali | 1786 | ite->PoLine.fromQPainterPath(clippedPath, true); |
19590 | jghali | 1787 | ite->ClipEdited = true; |
1788 | ite->FrameType = 3; |
||
1789 | ite->setFillShade(CurrFillShade); |
||
1790 | ite->setLineShade(100); |
||
23550 | jghali | 1791 | ite->setRotation(-angle); |
23536 | jghali | 1792 | // Only the new path has to be interpreted according to fillRule. QPainterPath |
1793 | // could decide to create a final path according to the other rule. Thus |
||
1794 | // we have to set this from the final path. |
||
1795 | ite->setFillEvenOdd(clippedPath.fillRule() == Qt::OddEvenFill); |
||
19590 | jghali | 1796 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
1797 | ite->setFillBlendmode(getBlendMode(state)); |
||
1798 | ite->setLineEnd(PLineEnd); |
||
1799 | ite->setLineJoin(PLineJoin); |
||
23536 | jghali | 1800 | ite->setWidthHeight(bbox.width(),bbox.height()); |
19590 | jghali | 1801 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
20694 | craig | 1802 | m_doc->adjustItemSize(ite); |
19590 | jghali | 1803 | m_Elements->append(ite); |
1804 | if (m_groupStack.count() != 0) |
||
1805 | { |
||
1806 | m_groupStack.top().Items.append(ite); |
||
1807 | applyMask(ite); |
||
1808 | } |
||
1809 | } |
||
1810 | } |
||
1811 | |||
1812 | GBool SlaOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) |
||
1813 | { |
||
23536 | jghali | 1814 | // qDebug() << "SlaOutputDev::axialShadedFill"; |
19590 | jghali | 1815 | double GrStartX; |
1816 | double GrStartY; |
||
1817 | double GrEndX; |
||
1818 | double GrEndY; |
||
1819 | int shade = 100; |
||
22741 | jghali | 1820 | POPPLER_CONST_070 Function *func = shading->getFunc(0); |
19590 | jghali | 1821 | VGradient FillGradient = VGradient(VGradient::linear); |
1822 | FillGradient.clearStops(); |
||
1823 | GfxColorSpace *color_space = shading->getColorSpace(); |
||
1824 | if (func->getType() == 3) |
||
1825 | { |
||
1826 | StitchingFunction *stitchingFunc = (StitchingFunction*)func; |
||
22741 | jghali | 1827 | const double *bounds = stitchingFunc->getBounds(); |
19590 | jghali | 1828 | int num_funcs = stitchingFunc->getNumFuncs(); |
22978 | jghali | 1829 | double domain_min = stitchingFunc->getDomainMin(0); |
1830 | double domain_max = stitchingFunc->getDomainMax(0); |
||
1831 | if (fabs(domain_max - domain_min) < 1e-6) |
||
1832 | { |
||
1833 | domain_min = 0.0; |
||
1834 | domain_max = 1.0; |
||
1835 | } |
||
19590 | jghali | 1836 | // Add stops from all the stitched functions |
22978 | jghali | 1837 | for (int i = 0 ; i <= num_funcs ; i++) |
19590 | jghali | 1838 | { |
1839 | GfxColor temp; |
||
22978 | jghali | 1840 | shading->getColor(bounds[i], &temp); |
19590 | jghali | 1841 | QString stopColor = getColor(color_space, &temp, &shade); |
22978 | jghali | 1842 | double stopPoint = (bounds[i] - domain_min) / (domain_max - domain_min); |
1843 | FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor], m_doc, shade), stopPoint, 0.5, 1.0, stopColor, shade ); |
||
19590 | jghali | 1844 | } |
1845 | } |
||
1846 | else if ((func->getType() == 2) || (func->getType() == 0)) |
||
1847 | { |
||
1848 | GfxColor stop1; |
||
22978 | jghali | 1849 | shading->getColor(0.0, &stop1); |
19590 | jghali | 1850 | QString stopColor1 = getColor(color_space, &stop1, &shade); |
1851 | FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor1], m_doc, shade), 0.0, 0.5, 1.0, stopColor1, shade ); |
||
1852 | GfxColor stop2; |
||
22978 | jghali | 1853 | shading->getColor(1.0, &stop2); |
19590 | jghali | 1854 | QString stopColor2 = getColor(color_space, &stop2, &shade); |
1855 | FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor2], m_doc, shade), 1.0, 0.5, 1.0, stopColor2, shade ); |
||
1856 | } |
||
22978 | jghali | 1857 | shading->getCoords(&GrStartX, &GrStartY, &GrEndX, &GrEndY); |
19590 | jghali | 1858 | double xmin, ymin, xmax, ymax; |
1859 | // get the clip region bbox |
||
1860 | state->getClipBBox(&xmin, &ymin, &xmax, &ymax); |
||
1861 | QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); |
||
1862 | crect = crect.normalized(); |
||
23588 | jghali | 1863 | QPainterPath out; |
1864 | out.addRect(crect); |
||
1865 | if (checkClip()) |
||
1866 | { |
||
1867 | // Apply the clip path early to adjust the gradient vector to the |
||
1868 | // smaller boundign box. |
||
1869 | out = intersection(m_currentClipPath, out); |
||
1870 | crect = out.boundingRect(); |
||
1871 | } |
||
22741 | jghali | 1872 | const double *ctm = state->getCTM(); |
19590 | jghali | 1873 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
1874 | FPointArray gr; |
||
1875 | gr.addPoint(GrStartX, GrStartY); |
||
1876 | gr.addPoint(GrEndX, GrEndY); |
||
1877 | gr.map(m_ctm); |
||
23588 | jghali | 1878 | gr.translate(-crect.x(), -crect.y()); |
1879 | |||
1880 | // Undo the rotation and translation of the gradient vector. |
||
1881 | double angle = m_ctm.map(QLineF(0, 0, 1, 0)).angle(); |
||
1882 | QTransform mm; |
||
1883 | mm.rotate(angle); |
||
1884 | out.translate(-crect.x(), -crect.y()); |
||
1885 | out = mm.map(out); |
||
1886 | QRectF bb = out.boundingRect(); |
||
1887 | gr.map(mm); |
||
1888 | gr.translate(-bb.left(), -bb.top()); |
||
1889 | GrStartX = gr.point(0).x(); |
||
1890 | GrStartY = gr.point(0).y(); |
||
1891 | GrEndX = gr.point(1).x(); |
||
1892 | GrEndY = gr.point(1).y(); |
||
1893 | |||
19590 | jghali | 1894 | double xCoor = m_doc->currentPage()->xOffset(); |
1895 | double yCoor = m_doc->currentPage()->yOffset(); |
||
1896 | QString output = QString("M %1 %2").arg(0.0).arg(0.0); |
||
1897 | output += QString("L %1 %2").arg(crect.width()).arg(0.0); |
||
1898 | output += QString("L %1 %2").arg(crect.width()).arg(crect.height()); |
||
1899 | output += QString("L %1 %2").arg(0.0).arg(crect.height()); |
||
1900 | output += QString("L %1 %2").arg(0.0).arg(0.0); |
||
1901 | output += QString("Z"); |
||
1902 | pathIsClosed = true; |
||
1903 | Coords = output; |
||
23588 | jghali | 1904 | int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), bb.width(), bb.height(), 0, CurrColorFill, CommonStrings::None); |
19590 | jghali | 1905 | PageItem* ite = m_doc->Items->at(z); |
20011 | fschmid | 1906 | if (checkClip()) |
1907 | { |
||
23536 | jghali | 1908 | ite->PoLine.fromQPainterPath(out, true); |
1909 | ite->setFillEvenOdd(out.fillRule() == Qt::OddEvenFill); |
||
20011 | fschmid | 1910 | } |
23588 | jghali | 1911 | ite->setRotation(-angle); |
19590 | jghali | 1912 | ite->ClipEdited = true; |
1913 | ite->FrameType = 3; |
||
1914 | ite->setFillShade(CurrFillShade); |
||
1915 | ite->setLineShade(100); |
||
1916 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
1917 | ite->setFillBlendmode(getBlendMode(state)); |
||
1918 | ite->setLineEnd(PLineEnd); |
||
1919 | ite->setLineJoin(PLineJoin); |
||
1920 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
1921 | ite->GrType = 6; |
||
1922 | if (!shading->getExtend0() || !shading->getExtend1()) |
||
1923 | { |
||
1924 | FillGradient.setRepeatMethod(VGradient::none); |
||
1925 | ite->setGradientExtend(VGradient::none); |
||
1926 | } |
||
1927 | else |
||
1928 | { |
||
1929 | FillGradient.setRepeatMethod(VGradient::pad); |
||
1930 | ite->setGradientExtend(VGradient::pad); |
||
1931 | } |
||
1932 | ite->fill_gradient = FillGradient; |
||
1933 | ite->setGradientVector(GrStartX, GrStartY, GrEndX, GrEndY, 0, 0, 1, 0); |
||
20694 | craig | 1934 | m_doc->adjustItemSize(ite); |
19590 | jghali | 1935 | m_Elements->append(ite); |
1936 | if (m_groupStack.count() != 0) |
||
1937 | { |
||
1938 | m_groupStack.top().Items.append(ite); |
||
1939 | applyMask(ite); |
||
1940 | } |
||
1941 | return gTrue; |
||
1942 | } |
||
1943 | |||
1944 | GBool SlaOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax) |
||
1945 | { |
||
23536 | jghali | 1946 | // qDebug() << "SlaOutputDev::radialShadedFill"; |
19590 | jghali | 1947 | double GrStartX; |
1948 | double GrStartY; |
||
1949 | double GrEndX; |
||
1950 | double GrEndY; |
||
1951 | int shade = 100; |
||
22741 | jghali | 1952 | POPPLER_CONST_070 Function *func = shading->getFunc(0); |
19590 | jghali | 1953 | VGradient FillGradient = VGradient(VGradient::linear); |
1954 | FillGradient.clearStops(); |
||
1955 | GfxColorSpace *color_space = shading->getColorSpace(); |
||
1956 | if (func->getType() == 3) |
||
1957 | { |
||
1958 | StitchingFunction *stitchingFunc = (StitchingFunction*)func; |
||
22741 | jghali | 1959 | const double *bounds = stitchingFunc->getBounds(); |
19590 | jghali | 1960 | int num_funcs = stitchingFunc->getNumFuncs(); |
22978 | jghali | 1961 | double domain_min = stitchingFunc->getDomainMin(0); |
1962 | double domain_max = stitchingFunc->getDomainMax(0); |
||
1963 | if (fabs(domain_max - domain_min) < 1e-6) |
||
1964 | { |
||
1965 | domain_min = 0.0; |
||
1966 | domain_max = 1.0; |
||
1967 | } |
||
19590 | jghali | 1968 | // Add stops from all the stitched functions |
22978 | jghali | 1969 | for (int i = 0 ; i <= num_funcs ; i++) |
19590 | jghali | 1970 | { |
1971 | GfxColor temp; |
||
22978 | jghali | 1972 | shading->getColor(bounds[i], &temp); |
19590 | jghali | 1973 | QString stopColor = getColor(color_space, &temp, &shade); |
22978 | jghali | 1974 | double stopPoint = (bounds[i] - domain_min) / (domain_max - domain_min); |
1975 | FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor], m_doc, shade), stopPoint, 0.5, 1.0, stopColor, shade ); |
||
19590 | jghali | 1976 | } |
1977 | } |
||
1978 | else if ((func->getType() == 2) || (func->getType() == 0)) |
||
1979 | { |
||
1980 | GfxColor stop1; |
||
22978 | jghali | 1981 | shading->getColor(0.0, &stop1); |
19590 | jghali | 1982 | QString stopColor1 = getColor(color_space, &stop1, &shade); |
1983 | FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor1], m_doc, shade), 0.0, 0.5, 1.0, stopColor1, shade ); |
||
1984 | GfxColor stop2; |
||
22978 | jghali | 1985 | shading->getColor(1.0, &stop2); |
19590 | jghali | 1986 | QString stopColor2 = getColor(color_space, &stop2, &shade); |
1987 | FillGradient.addStop( ScColorEngine::getShadeColor(m_doc->PageColors[stopColor2], m_doc, shade), 1.0, 0.5, 1.0, stopColor2, shade ); |
||
1988 | } |
||
1989 | double r0, x1, y1, r1; |
||
22978 | jghali | 1990 | shading->getCoords(&GrStartX, &GrStartY, &r0, &x1, &y1, &r1); |
19590 | jghali | 1991 | double xmin, ymin, xmax, ymax; |
1992 | // get the clip region bbox |
||
1993 | state->getClipBBox(&xmin, &ymin, &xmax, &ymax); |
||
1994 | QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); |
||
1995 | crect = crect.normalized(); |
||
1996 | double GrFocalX = x1; |
||
1997 | double GrFocalY = y1; |
||
1998 | GrEndX = GrFocalX + r1; |
||
1999 | GrEndY = GrFocalY; |
||
22741 | jghali | 2000 | const double *ctm = state->getCTM(); |
19590 | jghali | 2001 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
2002 | FPointArray gr; |
||
2003 | gr.addPoint(GrStartX, GrStartY); |
||
2004 | gr.addPoint(GrEndX, GrEndY); |
||
2005 | gr.addPoint(GrFocalX, GrFocalY); |
||
2006 | gr.map(m_ctm); |
||
2007 | GrStartX = gr.point(0).x() - crect.x(); |
||
2008 | GrStartY = gr.point(0).y() - crect.y(); |
||
2009 | GrEndX = gr.point(1).x() - crect.x(); |
||
2010 | GrEndY = gr.point(1).y() - crect.y(); |
||
2011 | GrFocalX = gr.point(2).x() - crect.x(); |
||
2012 | GrFocalY = gr.point(2).y() - crect.y(); |
||
2013 | double xCoor = m_doc->currentPage()->xOffset(); |
||
2014 | double yCoor = m_doc->currentPage()->yOffset(); |
||
2015 | QString output = QString("M %1 %2").arg(0.0).arg(0.0); |
||
2016 | output += QString("L %1 %2").arg(crect.width()).arg(0.0); |
||
2017 | output += QString("L %1 %2").arg(crect.width()).arg(crect.height()); |
||
2018 | output += QString("L %1 %2").arg(0.0).arg(crect.height()); |
||
2019 | output += QString("L %1 %2").arg(0.0).arg(0.0); |
||
2020 | output += QString("Z"); |
||
2021 | pathIsClosed = true; |
||
2022 | Coords = output; |
||
20561 | jghali | 2023 | int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, CurrColorFill, CommonStrings::None); |
19590 | jghali | 2024 | PageItem* ite = m_doc->Items->at(z); |
20011 | fschmid | 2025 | if (checkClip()) |
2026 | { |
||
23536 | jghali | 2027 | QPainterPath out = m_currentClipPath; |
23319 | jghali | 2028 | out.translate(m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset()); |
2029 | out.translate(-ite->xPos(), -ite->yPos()); |
||
23536 | jghali | 2030 | ite->PoLine.fromQPainterPath(out, true); |
2031 | ite->setFillEvenOdd(out.fillRule() == Qt::OddEvenFill); |
||
20011 | fschmid | 2032 | } |
19590 | jghali | 2033 | ite->ClipEdited = true; |
2034 | ite->FrameType = 3; |
||
2035 | ite->setFillShade(CurrFillShade); |
||
2036 | ite->setLineShade(100); |
||
2037 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
2038 | ite->setFillBlendmode(getBlendMode(state)); |
||
2039 | ite->setLineEnd(PLineEnd); |
||
2040 | ite->setLineJoin(PLineJoin); |
||
2041 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
2042 | ite->GrType = 7; |
||
2043 | if (!shading->getExtend0() || !shading->getExtend1()) |
||
2044 | { |
||
2045 | FillGradient.setRepeatMethod(VGradient::none); |
||
2046 | ite->setGradientExtend(VGradient::none); |
||
2047 | } |
||
2048 | else |
||
2049 | { |
||
2050 | FillGradient.setRepeatMethod(VGradient::pad); |
||
2051 | ite->setGradientExtend(VGradient::pad); |
||
2052 | } |
||
2053 | ite->fill_gradient = FillGradient; |
||
2054 | ite->setGradientVector(GrStartX, GrStartY, GrEndX, GrEndY, GrFocalX, GrFocalY, 1, 0); |
||
20694 | craig | 2055 | m_doc->adjustItemSize(ite); |
19590 | jghali | 2056 | m_Elements->append(ite); |
2057 | if (m_groupStack.count() != 0) |
||
2058 | { |
||
2059 | m_groupStack.top().Items.append(ite); |
||
2060 | applyMask(ite); |
||
2061 | } |
||
2062 | return gTrue; |
||
2063 | } |
||
2064 | |||
2065 | GBool SlaOutputDev::gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading) |
||
2066 | { |
||
23536 | jghali | 2067 | // qDebug() << "SlaOutputDev::gouraudTriangleShadedFill"; |
19590 | jghali | 2068 | double xCoor = m_doc->currentPage()->xOffset(); |
2069 | double yCoor = m_doc->currentPage()->yOffset(); |
||
2070 | double xmin, ymin, xmax, ymax; |
||
2071 | // get the clip region bbox |
||
2072 | state->getClipBBox(&xmin, &ymin, &xmax, &ymax); |
||
2073 | QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); |
||
2074 | crect = crect.normalized(); |
||
2075 | QString output = QString("M %1 %2").arg(0.0).arg(0.0); |
||
2076 | output += QString("L %1 %2").arg(crect.width()).arg(0.0); |
||
2077 | output += QString("L %1 %2").arg(crect.width()).arg(crect.height()); |
||
2078 | output += QString("L %1 %2").arg(0.0).arg(crect.height()); |
||
2079 | output += QString("L %1 %2").arg(0.0).arg(0.0); |
||
2080 | output += QString("Z"); |
||
2081 | pathIsClosed = true; |
||
2082 | Coords = output; |
||
22741 | jghali | 2083 | const double *ctm = state->getCTM(); |
19590 | jghali | 2084 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |