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 #include "scpageoutput.h"
8
9 #include <QList>
10 #include <QPointF>
11 #include <QRectF>
12 #include <QStack>
13 #include <pageitem_textframe.h>
14 #include "cmsettings.h"
15 #include "collapsedtablepainterex.h"
16 #include "commonstrings.h"
17 #include "pageitem.h"
18 #include "pageitem_arc.h"
19 #include "pageitem_group.h"
20 #include "pageitem_imageframe.h"
21 #include "pageitem_line.h"
22 #include "pageitem_polygon.h"
23 #include "pageitem_polyline.h"
24 #include "pageitem_regularpolygon.h"
25 #include "pageitem_spiral.h"
26 #include "pageitem_table.h"
27 #include "prefsmanager.h"
28 #include "scfonts.h"
29 #include "scimage.h"
30 #include "scpage.h"
31 #include "scpattern.h"
32 #include "text/textlayoutpainter.h"
33
34 #include "scribusdoc.h"
35 #include "util.h"
36 #include "util_formats.h"
37 #include "util_math.h"
38 #include "text/boxes.h"
39
40
MarksOptions()41 MarksOptions::MarksOptions()
42 {
43 markLength = 20.0;
44 markOffset = 0.0;
45 BleedTop = 0.0;
46 BleedLeft = 0.0;
47 BleedRight = 0.0;
48 BleedBottom = 0.0;
49 cropMarks = false;
50 bleedMarks = false;
51 registrationMarks = false;
52 colorMarks = false;
53 docInfoMarks = false;
54 }
55
MarksOptions(struct PrintOptions & opt)56 MarksOptions::MarksOptions(struct PrintOptions& opt)
57 {
58 markLength = opt.markLength;
59 markOffset = opt.markOffset;
60 BleedTop = opt.bleeds.top();
61 BleedLeft = opt.bleeds.left();
62 BleedRight = opt.bleeds.right();
63 BleedBottom = opt.bleeds.bottom();
64 cropMarks = opt.cropMarks;
65 bleedMarks = opt.bleedMarks;
66 registrationMarks = opt.registrationMarks;
67 colorMarks = opt.colorMarks;
68 docInfoMarks = true;
69 }
70
ScPageOutput(ScribusDoc * doc,bool reloadImages,int resolution,bool useProfiles)71 ScPageOutput::ScPageOutput(ScribusDoc* doc, bool reloadImages, int resolution, bool useProfiles)
72 : m_marksOptions()
73 {
74 m_doc = doc;
75 m_reloadImages = reloadImages;
76 m_imageRes = resolution;
77 m_useProfiles = useProfiles;
78 }
79
translateImageModeToRequest(ScPainterExBase::ImageMode mode)80 ScImage::RequestType ScPageOutput::translateImageModeToRequest(ScPainterExBase::ImageMode mode)
81 {
82 ScImage::RequestType value = ScImage::RGBData;
83 if (mode == ScPainterExBase::cmykImages)
84 value = ScImage::CMYKData;
85 else if (mode == ScPainterExBase::rgbImages)
86 value = ScImage::RGBData;
87 else if (mode == ScPainterExBase::rawImages)
88 value = ScImage::RawData;
89 return value;
90 }
91
drawPage(ScPage * page,ScPainterExBase * painter)92 void ScPageOutput::drawPage(ScPage* page, ScPainterExBase* painter)
93 {
94 int clipx = static_cast<int>(page->xOffset());
95 int clipy = static_cast<int>(page->yOffset());
96 int clipw = qRound(page->width());
97 int cliph = qRound(page->height());
98 ScLayer layer;
99 layer.isViewable = false;
100 uint layerCount = m_doc->layerCount();
101 for (uint la = 0; la < layerCount; ++la)
102 {
103 m_doc->Layers.levelToLayer(layer, la);
104 drawMasterItems(painter, page, layer, QRect(clipx, clipy, clipw, cliph));
105 drawPageItems(painter, page, layer, QRect(clipx, clipy, clipw, cliph));
106 }
107 drawMarks(page, painter, m_marksOptions);
108 }
109
drawMasterItems(ScPainterExBase * painter,ScPage * page,ScLayer & layer,QRect clip)110 void ScPageOutput::drawMasterItems(ScPainterExBase *painter, ScPage *page, ScLayer& layer, QRect clip)
111 {
112 PageItem* currItem;
113 if (page->masterPageNameEmpty())
114 return;
115 if (page->FromMaster.count() <= 0)
116 return;
117 if (!layer.isViewable || !layer.isPrintable)
118 return;
119 ScPage* Mp = m_doc->MasterPages.at(m_doc->MasterNames[page->masterPageName()]);
120 int pageFromMasterCount = page->FromMaster.count();
121 for (int i = 0; i < pageFromMasterCount; ++i)
122 {
123 currItem = page->FromMaster.at(i);
124 if (currItem->m_layerID != layer.ID)
125 continue;
126 if ((currItem->OwnPage != -1) && (currItem->OwnPage != static_cast<int>(Mp->pageNr())))
127 continue;
128 if (!currItem->printEnabled())
129 continue;
130 int savedOwnPage = currItem->OwnPage;
131 double OldX = currItem->xPos();
132 double OldY = currItem->yPos();
133 double OldBX = currItem->BoundingX;
134 double OldBY = currItem->BoundingY;
135 currItem->OwnPage = page->pageNr();
136 if (!currItem->ChangedMasterItem)
137 {
138 currItem->moveBy(-Mp->xOffset() + page->xOffset(), -Mp->yOffset() + page->yOffset(), true);
139 currItem->BoundingX = OldBX - Mp->xOffset() + page->xOffset();
140 currItem->BoundingY = OldBY - Mp->yOffset() + page->yOffset();
141 }
142 QRectF oldR(currItem->getBoundingRect().adjusted(0.0, 0.0, 1.0, 1.0));
143 if (clip.intersects(oldR.toRect()))
144 drawItem(currItem, painter, clip);
145 currItem->OwnPage = savedOwnPage;
146 if (!currItem->ChangedMasterItem)
147 {
148 currItem->setXYPos(OldX, OldY, true);
149 currItem->BoundingX = OldBX;
150 currItem->BoundingY = OldBY;
151 }
152 }
153 }
154
drawPageItems(ScPainterExBase * painter,ScPage * page,ScLayer & layer,QRect clip)155 void ScPageOutput::drawPageItems(ScPainterExBase *painter, ScPage *page, ScLayer& layer, QRect clip)
156 {
157 PageItem *currItem;
158 if (m_doc->Items->count() <= 0)
159 return;
160 if (!layer.isViewable || !layer.isPrintable)
161 return;
162 int docCurrPageNo = static_cast<int>(page->pageNr());
163 for (int it = 0; it < m_doc->Items->count(); ++it)
164 {
165 currItem = m_doc->Items->at(it);
166 if (currItem->m_layerID != layer.ID)
167 continue;
168 if (!currItem->printEnabled())
169 continue;
170 if ((m_doc->masterPageMode()) && ((currItem->OwnPage != -1) && (currItem->OwnPage != docCurrPageNo)))
171 continue;
172 if (!m_doc->masterPageMode() && !currItem->OnMasterPage.isEmpty())
173 {
174 if (currItem->OnMasterPage != page->pageName())
175 continue;
176 }
177 QRectF oldR(currItem->getBoundingRect().adjusted(0.0, 0.0, 1.0, 1.0));
178 if (clip.intersects(oldR.toRect()))
179 {
180 drawItem(currItem, painter, clip);
181 }
182 }
183 }
184
drawItem(PageItem * item,ScPainterExBase * painter,QRect clip)185 void ScPageOutput::drawItem(PageItem* item, ScPainterExBase* painter, QRect clip)
186 {
187 if (clip.isNull())
188 {
189 clip = QRectF(QPointF(m_doc->minCanvasCoordinate.x(), m_doc->minCanvasCoordinate.y()),
190 QPointF(m_doc->maxCanvasCoordinate.x(), m_doc->maxCanvasCoordinate.y())).toAlignedRect();
191 }
192
193 drawItem_Pre(item, painter);
194 PageItem::ItemType itemType = item->itemType();
195 if (itemType == PageItem::Arc)
196 drawItem_Arc((PageItem_Arc*) item, painter, clip);
197 else if (itemType == PageItem::Group)
198 drawItem_Group((PageItem_Group*) item, painter, clip);
199 else if (itemType == PageItem::ImageFrame)
200 drawItem_ImageFrame((PageItem_ImageFrame*) item, painter, clip);
201 else if (itemType == PageItem::Line)
202 drawItem_Line((PageItem_Line*) item, painter, clip);
203 else if (itemType == PageItem::Polygon)
204 drawItem_Polygon((PageItem_Polygon*) item, painter, clip);
205 else if (itemType == PageItem::PolyLine)
206 drawItem_PolyLine((PageItem_PolyLine*) item, painter, clip);
207 else if (itemType == PageItem::RegularPolygon)
208 drawItem_RegularPolygon((PageItem_RegularPolygon*) item, painter, clip);
209 else if (itemType == PageItem::Spiral)
210 drawItem_Spiral((PageItem_Spiral*) item, painter, clip);
211 else if (itemType == PageItem::Table)
212 drawItem_Table((PageItem_Table*) item, painter, clip);
213 else if (itemType == PageItem::TextFrame || itemType == PageItem::PathText)
214 drawItem_Text(item, painter, clip);
215 drawItem_Post(item, painter);
216 }
217
drawItem_Pre(PageItem * item,ScPainterExBase * painter)218 void ScPageOutput::drawItem_Pre(PageItem* item, ScPainterExBase* painter)
219 {
220 painter->save();
221 if (!item->isEmbedded)
222 painter->translate(item->xPos(), item->yPos());
223 painter->rotate(item->rotation());
224 painter->setBlendModeFill(item->fillBlendmode());
225 painter->setLineWidth(item->lineWidth());
226 if (item->isGroup())
227 return;
228 if (item->GrType == Gradient_Pattern)
229 {
230 QString pat = item->pattern();
231 ScPattern *pattern = m_doc->checkedPattern(pat);
232 if (!pattern)
233 {
234 painter->m_fillGradient = VGradientEx(VGradientEx::linear);
235 if (item->fillColor() != CommonStrings::None)
236 {
237 painter->setBrush(ScColorShade(m_doc->PageColors[item->fillColor()], (int) item->fillShade()));
238 painter->setFillMode(ScPainterExBase::Solid);
239 }
240 else
241 painter->setFillMode(ScPainterExBase::None);
242 }
243 else
244 {
245 QTransform patternTransform;
246 double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY;
247 bool patternMirrorX, patternMirrorY;
248 item->patternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
249 item->patternFlip(patternMirrorX, patternMirrorY);
250 painter->setPattern(pattern, patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, patternMirrorX, patternMirrorY);
251 painter->setFillMode(ScPainterExBase::Pattern);
252 }
253 }
254 else if (item->GrType == Gradient_4Colors)
255 {
256 painter->setFillMode(ScPainterExBase::Gradient);
257 FPoint pG1 = FPoint(0, 0);
258 FPoint pG2 = FPoint(item->width(), 0);
259 FPoint pG3 = FPoint(item->width(), item->height());
260 FPoint pG4 = FPoint(0, item->height());
261 ScColorShade col1(m_doc->PageColors[item->GrColorP1], item->GrCol1Shade);
262 ScColorShade col2(m_doc->PageColors[item->GrColorP2], item->GrCol2Shade);
263 ScColorShade col3(m_doc->PageColors[item->GrColorP3], item->GrCol3Shade);
264 ScColorShade col4(m_doc->PageColors[item->GrColorP4], item->GrCol4Shade);
265 painter->set4ColorGeometry(pG1, pG2, pG3, pG4, item->GrControl1, item->GrControl2, item->GrControl3, item->GrControl4);
266 painter->set4ColorColors(col1, col2, col3, col4);
267 }
268 else if (item->GrType != 0)
269 {
270 QString gradientVal = item->gradient();
271 if ((!gradientVal.isEmpty()) && (!m_doc->docGradients.contains(gradientVal)))
272 gradientVal = "";
273 if (!(gradientVal.isEmpty()) && (m_doc->docGradients.contains(gradientVal)))
274 painter->m_fillGradient = VGradientEx(m_doc->docGradients[gradientVal], *m_doc);
275 if ((painter->m_fillGradient.stops() < 2) && (item->GrType < Gradient_4Colors)) // fall back to solid filling if there are not enough colorstops in the gradient.
276 {
277 if (item->fillColor() != CommonStrings::None)
278 {
279 painter->setBrush(ScColorShade(m_doc->PageColors[item->fillColor()], (int) item->fillShade()));
280 painter->setFillMode(ScPainterExBase::Solid);
281 }
282 else
283 painter->setFillMode(ScPainterExBase::None);
284 }
285 else
286 {
287 FPoint fpStart(item->GrStartX, item->GrStartY), fpEnd(item->GrEndX, item->GrEndY);
288 FPoint fpFocal(item->GrFocalX, item->GrFocalY);
289 painter->setFillMode(ScPainterExBase::Gradient);
290 painter->m_fillGradient = VGradientEx(item->fill_gradient, *m_doc);
291 switch (item->GrType)
292 {
293 case 1:
294 case 2:
295 case 3:
296 case 4:
297 case 6:
298 painter->setGradient(VGradientEx::linear, fpStart, fpEnd, fpStart, item->GrScale, item->GrSkew);
299 break;
300 case 5:
301 case 7:
302 painter->setGradient(VGradientEx::radial, fpStart, fpEnd, fpFocal, item->GrScale, item->GrSkew);
303 break;
304 case 10:
305 painter->setFillMode(ScPainterExBase::Gradient);
306 painter->setDiamondGeometry(FPoint(0, 0), FPoint(item->width(), 0), FPoint(item->width(), item->height()), FPoint(0, item->height()),
307 item->GrControl1, item->GrControl2, item->GrControl3, item->GrControl4, item->GrControl5);
308 break;
309 case 11:
310 case 13:
311 painter->setFillMode(ScPainterExBase::Gradient);
312 painter->setMeshGradient(FPoint(0, 0), FPoint(item->width(), 0), FPoint(item->width(), item->height()), FPoint(0, item->height()), item->meshGradientArray);
313 break;
314 case 12:
315 painter->setFillMode(ScPainterExBase::Gradient);
316 painter->setMeshGradient(FPoint(0, 0), FPoint(item->width(), 0), FPoint(item->width(), item->height()), FPoint(0, item->height()), item->meshGradientPatches);
317 break;
318 }
319 }
320 }
321 else
322 {
323 painter->m_fillGradient = VGradientEx(VGradientEx::linear);
324 if (item->fillColor() != CommonStrings::None)
325 {
326 painter->setBrush(ScColorShade(m_doc->PageColors[item->fillColor()], (int) item->fillShade()));
327 painter->setFillMode(ScPainterExBase::Solid);
328 }
329 else
330 painter->setFillMode(ScPainterExBase::None);
331 }
332 if (item->lineColor() != CommonStrings::None)
333 {
334 if ((item->lineWidth() == 0) && !item->asLine())
335 painter->setLineWidth(0);
336 else
337 {
338 ScColorShade tmp(m_doc->PageColors[item->lineColor()], (int) item->lineShade());
339 painter->setPen(tmp , item->lineWidth(), item->PLineArt, item->PLineEnd, item->PLineJoin);
340 if (item->DashValues.count() != 0)
341 painter->setDash(item->DashValues, item->DashOffset);
342 }
343 }
344 else
345 painter->setLineWidth(0);
346 painter->setBrushOpacity(1.0 - item->fillTransparency());
347 painter->setPenOpacity(1.0 - item->lineTransparency());
348 painter->setFillRule(item->fillRule);
349
350 if ((item->GrMask == GradMask_Linear) || (item->GrMask == GradMask_Radial) || (item->GrMask == GradMask_LinearLumAlpha) || (item->GrMask == GradMask_RadialLumAlpha))
351 {
352 QString gradientMaskVal = item->gradientMaskVal;
353 FPoint fpMaskStart(item->GrMaskStartX, item->GrMaskStartY);
354 FPoint fpMaskEnd(item->GrMaskEndX, item->GrMaskEndY);
355 FPoint fpMaskFocal(item->GrMaskFocalX, item->GrMaskFocalY);
356 if ((item->GrMask == GradMask_Linear) || (item->GrMask == GradMask_Radial))
357 painter->setMaskMode(1);
358 else
359 painter->setMaskMode(3);
360 if ((!gradientMaskVal.isEmpty()) && (!m_doc->docGradients.contains(gradientMaskVal)))
361 gradientMaskVal = "";
362 if (!(gradientMaskVal.isEmpty()) && (m_doc->docGradients.contains(gradientMaskVal)))
363 painter->m_maskGradient = VGradientEx(m_doc->docGradients[gradientMaskVal], *m_doc);
364 if ((item->GrMask == GradMask_Linear) || (item->GrMask == GradMask_LinearLumAlpha))
365 painter->setGradientMask(VGradientEx::linear, fpMaskStart, fpMaskEnd, fpMaskStart, item->GrMaskScale, item->GrMaskSkew);
366 else
367 painter->setGradientMask(VGradientEx::radial, fpMaskStart, fpMaskEnd, fpMaskFocal, item->GrMaskScale, item->GrMaskSkew);
368 }
369 else if ((item->GrMask == GradMask_Pattern) || (item->GrMask == GradMask_PatternLumAlpha) || (item->GrMask == GradMask_PatternLumAlphaInverted) || (item->GrMask == GradMask_PatternInverted))
370 {
371 QString patternMaskVal = item->patternMaskVal;
372 ScPattern *patternMask = m_doc->checkedPattern(patternMaskVal);
373 if (patternMask)
374 {
375 painter->setPatternMask(patternMask, item->patternMaskScaleX, item->patternMaskScaleY, item->patternMaskOffsetX, item->patternMaskOffsetY,
376 item->patternMaskRotation, item->patternMaskSkewX, item->patternMaskSkewY, item->patternMaskMirrorX, item->patternMaskMirrorY);
377 if (item->GrMask == GradMask_Pattern)
378 painter->setMaskMode(2);
379 else if (item->GrMask == GradMask_PatternLumAlpha)
380 painter->setMaskMode(4);
381 else if (item->GrMask == GradMask_PatternLumAlphaInverted)
382 painter->setMaskMode(5);
383 else
384 painter->setMaskMode(6);
385 }
386 else
387 {
388 painter->setMaskMode(0);
389 }
390 }
391 else
392 painter->setMaskMode(0);
393 }
394
drawItem_Post(PageItem * item,ScPainterExBase * painter)395 void ScPageOutput::drawItem_Post(PageItem* item, ScPainterExBase* painter)
396 {
397 bool doStroke = true;
398 if (!item->isGroup())
399 {
400 painter->setMaskMode(0);
401 if (item->isGroup() || item->isLine() || item->isPathText() || item->isPolyLine() || item->isSpiral() || item->isSymbol() || item->isTable())
402 doStroke = false;
403 if (doStroke)
404 {
405 painter->setBlendModeStroke(item->lineBlendmode());
406 painter->setPenOpacity(1.0 - item->lineTransparency());
407 if ((item->lineColor() != CommonStrings::None)|| (!item->strokePattern().isEmpty()) || (item->strokeGradientType() > 0))
408 {
409 ScColorShade tmp(m_doc->PageColors[item->lineColor()], (int) item->lineShade());
410 painter->setPen(tmp, item->lineWidth(), item->PLineArt, item->PLineEnd, item->PLineJoin);
411 if (item->DashValues.count() != 0)
412 painter->setDash(item->DashValues, item->DashOffset);
413 }
414 else
415 painter->setLineWidth(0);
416 if ((item->itemType() == PageItem::LatexFrame) || (item->itemType() == PageItem::ImageFrame) || (item->itemType() == PageItem::TextFrame) || (item->itemType() == PageItem::OSGFrame))
417 painter->setupPolygon(&item->PoLine);
418 if (item->NamedLStyle.isEmpty())
419 {
420 QString patternStrokeVal = item->strokePattern();
421 ScPattern *strokePattern = m_doc->checkedPattern(patternStrokeVal);
422 if (strokePattern)
423 {
424 if (item->patternStrokePath)
425 {
426 QPainterPath guidePath = item->PoLine.toQPainterPath(false);
427 drawStrokePattern(item, painter, guidePath);
428 }
429 else
430 {
431 painter->setPattern(strokePattern, item->patternStrokeScaleX, item->patternStrokeScaleY, item->patternStrokeOffsetX, item->patternStrokeOffsetY, item->patternStrokeRotation, item->patternStrokeSkewX, item->patternStrokeSkewY, item->patternStrokeMirrorX, item->patternStrokeMirrorY);
432 painter->setStrokeMode(ScPainterExBase::Pattern);
433 painter->strokePath();
434 }
435 }
436 else if (item->strokeGradientType() > 0)
437 {
438 QString gradientStrokeVal = item->strokeGradient();
439 if ((!gradientStrokeVal.isEmpty()) && (!m_doc->docGradients.contains(gradientStrokeVal)))
440 gradientStrokeVal.clear();
441 if (!(gradientStrokeVal.isEmpty()) && (m_doc->docGradients.contains(gradientStrokeVal)))
442 painter->m_strokeGradient = VGradientEx(m_doc->docGradients[gradientStrokeVal], *m_doc);
443 if (painter->m_strokeGradient.stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient.
444 {
445 if (item->lineColor() != CommonStrings::None)
446 {
447 ScColorShade strokeColor(m_doc->PageColors[item->lineColor()], item->lineShade());
448 painter->setBrush(strokeColor);
449 painter->setStrokeMode(ScPainterExBase::Solid);
450 }
451 else
452 painter->setStrokeMode(ScPainterExBase::None);
453 }
454 else
455 {
456 FPoint fpStart(item->GrStrokeStartX, item->GrStrokeStartY);
457 FPoint fpEnd(item->GrStrokeEndX, item->GrStrokeEndY);
458 FPoint fpFocal(item->GrStrokeFocalX, item->GrStrokeFocalY);
459 painter->setStrokeMode(ScPainterExBase::Gradient);
460 painter->m_strokeGradient = VGradientEx(item->stroke_gradient, *m_doc);
461 if (item->GrTypeStroke == Gradient_Linear)
462 painter->setGradient(VGradientEx::linear, fpStart, fpEnd, fpStart, item->GrStrokeScale, item->GrStrokeSkew);
463 else
464 painter->setGradient(VGradientEx::radial, fpStart, fpEnd, fpFocal, item->GrStrokeScale, item->GrStrokeSkew);
465 }
466 painter->strokePath();
467 }
468 else if (item->lineColor() != CommonStrings::None)
469 {
470 ScColorShade scColor(m_doc->PageColors[item->lineColor()], item->lineShade());
471 painter->setStrokeMode(ScPainterExBase::Solid);
472 painter->setPen(scColor, item->lineWidth(), item->PLineArt, item->PLineEnd, item->PLineJoin);
473 if (item->DashValues.count() != 0)
474 painter->setDash(item->DashValues, item->DashOffset);
475 painter->strokePath();
476 }
477 }
478 else
479 {
480 multiLine ml = m_doc->docLineStyles[item->NamedLStyle];
481 for (int it = ml.size() - 1; it > -1; it--)
482 {
483 const SingleLine& sl = ml[it];
484 if ((sl.Color != CommonStrings::None) && (sl.Width != 0))
485 {
486 ScColorShade tmp(m_doc->PageColors[sl.Color], sl.Shade);
487 painter->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash),
488 static_cast<Qt::PenCapStyle>(sl.LineEnd),
489 static_cast<Qt::PenJoinStyle>(sl.LineJoin));
490 painter->strokePath();
491 }
492 }
493 }
494 painter->setBlendModeStroke(0);
495 }
496 }
497 painter->setFillMode(ScPainterExBase::Solid);
498 painter->setBlendModeFill(0);
499 painter->setStrokeMode(ScPainterExBase::Solid);
500 painter->setBlendModeStroke(0);
501 painter->restore();
502 }
503
drawItem_Embedded(PageItem * item,ScPainterExBase * p,QRect clip,const CharStyle & style,PageItem * cembedded)504 void ScPageOutput::drawItem_Embedded(PageItem* item, ScPainterExBase *p, QRect clip, const CharStyle& style, PageItem* cembedded)
505 {
506 if (!cembedded)
507 return;
508 QList<PageItem*> emG;
509 emG.append(cembedded);
510 for (int em = 0; em < emG.count(); ++em)
511 {
512 PageItem* embedded = emG.at(em);
513 p->save();
514 double x = embedded->xPos();
515 double y = embedded->yPos();
516 embedded->setXPos(embedded->gXpos, true);
517 embedded->setYPos((embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos, true);
518 p->translate((embedded->gXpos * (style.scaleH() / 1000.0)), ( - (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos * (style.scaleV() / 1000.0)));
519 if (style.baselineOffset() != 0)
520 {
521 p->translate(0, -embedded->gHeight * (style.baselineOffset() / 1000.0));
522 embedded->setYPos(embedded->yPos() - embedded->gHeight * (style.baselineOffset() / 1000.0));
523 }
524 p->scale(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
525 double pws = embedded->m_lineWidth;
526 drawItem_Pre(embedded, p);
527 switch (embedded->itemType())
528 {
529 case PageItem::ImageFrame:
530 case PageItem::LatexFrame:
531 case PageItem::TextFrame:
532 case PageItem::Polygon:
533 case PageItem::PathText:
534 case PageItem::Symbol:
535 case PageItem::Group:
536 case PageItem::RegularPolygon:
537 case PageItem::Arc:
538 drawItem(embedded, p, clip);
539 break;
540 case PageItem::Line:
541 case PageItem::PolyLine:
542 embedded->m_lineWidth = pws * qMin(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
543 drawItem(embedded, p, clip);
544 break;
545 default:
546 break;
547 }
548 embedded->m_lineWidth = pws * qMin(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
549 drawItem_Post(embedded, p);
550 embedded->setXPos(x, true);
551 embedded->setYPos(y, true);
552 p->restore();
553 embedded->m_lineWidth = pws;
554 }
555 }
556
drawPattern(PageItem * item,ScPainterExBase * painter,QRect clip)557 void ScPageOutput::drawPattern(PageItem* item, ScPainterExBase* painter, QRect clip)
558 {
559 double x1, x2, y1, y2;
560 ScPattern& pattern = m_doc->docPatterns[item->pattern()];
561 double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY;
562 item->patternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
563
564 // Compute pattern tansformation matrix and its inverse for converting pattern coordinates
565 // to pageitem coordinates
566 QTransform matrix, invMat;
567 matrix.translate(patternOffsetX, patternOffsetY);
568 matrix.rotate(patternRotation);
569 matrix.shear(patternSkewX, patternSkewY);
570 matrix.scale(pattern.scaleX, pattern.scaleY);
571 matrix.scale(patternScaleX / 100.0 , patternScaleY / 100.0);
572 invMat.scale((patternScaleX != 0) ? (100 /patternScaleX) : 1.0, (patternScaleY != 0) ? (100 /patternScaleY) : 1.0);
573 invMat.scale((pattern.scaleX != 0) ? (1 /pattern.scaleX) : 1.0, (pattern.scaleY != 0) ? (1 /pattern.scaleY) : 1.0);
574 invMat.rotate(-patternRotation);
575 invMat.translate(-patternOffsetX, -patternOffsetY);
576
577 // Compute bounding box in which pattern item will be drawn
578 double width = item->width();
579 double height = item->height();
580 double rot = patternRotation - floor(patternRotation / 90) * 90;
581 double ctheta = cos(rot * M_PI / 180);
582 double stheta = sin(rot * M_PI / 180);
583 QRectF itemRect(0.0, 0.0, item->width(), item->height());
584 QPointF pa(width * stheta * stheta, -width * stheta * ctheta);
585 QPointF pb(width + height * ctheta * stheta, height * stheta * stheta);
586 QPointF pc(-height * ctheta * stheta, height * ctheta * ctheta);
587 QPointF pd(width * ctheta * ctheta, height + width * ctheta * stheta);
588 QPointF ipa = invMat.map(pa), ipb = invMat.map(pb);
589 QPointF ipc = invMat.map(pc), ipd = invMat.map(pd);
590
591 painter->save();
592 if (!item->imageClip.empty())
593 {
594 painter->setupPolygon(&item->imageClip);
595 painter->setClipPath();
596 }
597 painter->setupPolygon(&item->PoLine);
598 painter->setClipPath();
599 for (int index = 0; index < pattern.items.count(); index++)
600 {
601 QRectF itRect;
602 PageItem* it = pattern.items.at(index);
603
604 painter->save();
605 painter->translate(patternOffsetX, patternOffsetY);
606 painter->rotate(patternRotation);
607 painter->scale(pattern.scaleX, pattern.scaleY);
608 painter->scale(patternScaleX / 100.0, patternScaleY / 100.0);
609
610 double patWidth = (pattern.width != 0.0) ? pattern.width : 1.0;
611 double patHeight = (pattern.height != 0.0) ? pattern.height : 1.0;
612 double kxa = (ipa.x() - it->gXpos) / patWidth;
613 double kxb = (ipb.x() - it->gXpos) / patWidth;
614 double kxc = (ipc.x() - it->gXpos) / patWidth;
615 double kxd = (ipd.x() - it->gXpos) / patWidth;
616 double kya = (ipa.y() - it->gYpos) / patHeight;
617 double kyb = (ipb.y() - it->gYpos) / patHeight;
618 double kyc = (ipc.y() - it->gYpos) / patHeight;
619 double kyd = (ipd.y() - it->gYpos) / patHeight;
620 int kxMin = (int) floor(qMin(qMin(kxa, kxb), qMin(kxc, kxd)));
621 int kxMax = (int) ceil (qMax(qMax(kxa, kxb), qMax(kxc, kxd)));
622 int kyMin = (int) floor(qMin(qMin(kya, kyb), qMin(kyc, kyd)));
623 int kyMax = (int) ceil (qMax(qMax(kya, kyb), qMax(kyc, kyd)));
624
625 double itx = it->xPos();
626 double ity = it->yPos();
627 double itPosX = it->gXpos, itPosY = it->gYpos;
628 for (int kx = kxMin; kx <= kxMax; kx++)
629 {
630 for (int ky = kyMin; ky <= kyMax; ky++)
631 {
632 itPosX = it->gXpos + kx * pattern.width;
633 itPosY = it->gYpos + ky * pattern.height;
634 it->setXYPos(itPosX, itPosY);
635 it->getBoundingRect(&x1, &y1, &x2, &y2);
636 itRect.setCoords(x1, y1, x2, y2);
637 itRect = matrix.mapRect(itRect);
638 if (itRect.intersects(itemRect))
639 drawItem(it, painter, clip);
640 }
641 }
642 it->setXYPos(itx, ity);
643 painter->restore();
644 }
645 painter->restore();
646 }
647
drawStrokePattern(PageItem * item,ScPainterExBase * painter,const QPainterPath & path)648 void ScPageOutput::drawStrokePattern(PageItem* item, ScPainterExBase* painter, const QPainterPath& path)
649 {
650
651 }
652
drawItem_Arc(PageItem_Arc * item,ScPainterExBase * painter,QRect clip)653 void ScPageOutput::drawItem_Arc(PageItem_Arc* item , ScPainterExBase* painter, QRect clip)
654 {
655 painter->setupPolygon(&item->PoLine);
656 fillPath(item, painter, clip);
657 }
658
drawItem_Group(PageItem_Group * item,ScPainterExBase * painter,QRect clip)659 void ScPageOutput::drawItem_Group(PageItem_Group* item, ScPainterExBase* painter, QRect clip)
660 {
661 if (item->groupItemList.isEmpty())
662 return;
663
664 painter->save();
665 if (item->imageFlippedH())
666 {
667 painter->translate(item->width(), 0);
668 painter->scale(-1, 1);
669 }
670 if (item->imageFlippedV())
671 {
672 painter->translate(0, item->height());
673 painter->scale(1, -1);
674 }
675 /*if ((maskType() == 1) || (maskType() == 2) || (maskType() == 4) || (maskType() == 5))
676 {
677 if ((maskType() == 1) || (maskType() == 2))
678 painter->setMaskMode(1);
679 else
680 painter->setMaskMode(3);
681 if ((!gradientMask().isEmpty()) && (!m_Doc->docGradients.contains(gradientMask())))
682 gradientMaskVal = "";
683 if (!(gradientMask().isEmpty()) && (m_Doc->docGradients.contains(gradientMask())))
684 mask_gradient = m_Doc->docGradients[gradientMask()];
685 painter->mask_gradient = mask_gradient;
686 if ((maskType() == 1) || (maskType() == 4))
687 painter->setGradientMask(VGradient::linear, FPoint(GrMaskStartX, GrMaskStartY), FPoint(GrMaskEndX, GrMaskEndY), FPoint(GrMaskStartX, GrMaskStartY), GrMaskScale, GrMaskSkew);
688 else
689 painter->setGradientMask(VGradient::radial, FPoint(GrMaskStartX, GrMaskStartY), FPoint(GrMaskEndX, GrMaskEndY), FPoint(GrMaskFocalX, GrMaskFocalY), GrMaskScale, GrMaskSkew);
690 }
691 else if ((maskType() == 3) || (maskType() == 6) || (maskType() == 7) || (maskType() == 8))
692 {
693 if ((patternMask().isEmpty()) || (!m_Doc->docPatterns.contains(patternMask())))
694 painter->setMaskMode(0);
695 else
696 {
697 double scw = Width / groupWidth;
698 double sch = Height / groupHeight;
699 painter->setPatternMask(&m_Doc->docPatterns[patternMask()], patternMaskScaleX * scw, patternMaskScaleY * sch, patternMaskOffsetX, patternMaskOffsetY, patternMaskRotation, patternMaskSkewX, patternMaskSkewY, patternMaskMirrorX, patternMaskMirrorY);
700 if (maskType() == 3)
701 painter->setMaskMode(2);
702 else if (maskType() == 6)
703 painter->setMaskMode(4);
704 else if (maskType() == 7)
705 painter->setMaskMode(5);
706 else
707 painter->setMaskMode(6);
708 }
709 }
710 else*/
711 painter->setMaskMode(0);
712 painter->setFillRule(item->fillRule);
713 //painter->beginLayer(1.0 - fillTransparency(), fillBlendmode(), &PoLine);
714 painter->setMaskMode(0);
715 painter->scale(item->width() / item->groupWidth, item->height() / item->groupHeight);
716 for (int em = 0; em < item->groupItemList.count(); ++em)
717 {
718 PageItem* embedded = item->groupItemList.at(em);
719 painter->save();
720 painter->translate(embedded->gXpos, embedded->gYpos);
721 embedded->savedOwnPage = embedded->OwnPage;
722 embedded->OwnPage = item->OwnPage;
723 embedded->isEmbedded = true;
724 embedded->invalidateLayout();
725 drawItem(embedded, painter, QRect());
726 embedded->isEmbedded = false;
727 embedded->OwnPage = embedded->savedOwnPage;
728 painter->restore();
729 }
730 //painter->endLayer();
731 painter->restore();
732 }
733
drawItem_ImageFrame(PageItem_ImageFrame * item,ScPainterExBase * painter,QRect clip)734 void ScPageOutput::drawItem_ImageFrame(PageItem_ImageFrame* item, ScPainterExBase* painter, QRect clip)
735 {
736 ScPainterExBase::ImageMode mode = ScPainterExBase::rgbImages;
737 if ((item->fillColor() != CommonStrings::None) || (item->GrType != 0))
738 {
739 painter->setupPolygon(&item->PoLine);
740 fillPath(item, painter, clip);
741 }
742 if (item->Pfile.isEmpty())
743 {
744 /*painter->setPen(ScColorShade(Qt::black, 100), 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
745 painter->drawLine(FPoint(0, 0), FPoint(item->width(), item->height()));
746 painter->drawLine(FPoint(0, item->height()), FPoint(item->width(), 0));*/
747 }
748 else
749 {
750 if ((!item->imageVisible()) || (!item->imageIsAvailable))
751 {
752 /*painter->setPen(ScColorShade(Qt::red, 100), 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
753 painter->drawLine(FPoint(0, 0), FPoint(item->width(), item->height()));
754 painter->drawLine(FPoint(0, item->height()), FPoint(item->width(), 0));*/
755 }
756 else
757 {
758 ScImage scImg;
759 ScImage* pImage = nullptr;
760 double imScaleX = item->imageXScale();
761 double imScaleY = item->imageYScale();
762 if (m_reloadImages)
763 {
764 bool dummy;
765 bool useCmyk = false;
766 ScPainterExBase::ImageMode imageMode = painter->imageMode();
767 if (imageMode == ScPainterExBase::cmykImages)
768 useCmyk = true;
769 QFileInfo fInfo(item->Pfile);
770 QString ext = fInfo.suffix();
771 CMSettings cmsSettings(item->doc(), item->ImageProfile, item->ImageIntent);
772 cmsSettings.allowColorManagement(m_useProfiles);
773 cmsSettings.setUseEmbeddedProfile(item->UseEmbedded);
774 scImg.imgInfo.valid = false;
775 scImg.imgInfo.clipPath = "";
776 scImg.imgInfo.PDSpathData.clear();
777 scImg.imgInfo.layerInfo.clear();
778 scImg.imgInfo.RequestProps = item->pixm.imgInfo.RequestProps;
779 scImg.imgInfo.isRequest = item->pixm.imgInfo.isRequest;
780 scImg.loadPicture(item->Pfile, item->pixm.imgInfo.actualPageNumber, cmsSettings, translateImageModeToRequest(imageMode), m_imageRes, &dummy);
781 if (extensionIndicatesEPSorPS(ext) || extensionIndicatesPDF(ext))
782 {
783 imScaleX *= (72.0 / (double) m_imageRes);
784 imScaleY *= (72.0 / (double) m_imageRes);
785 }
786 scImg.applyEffect(item->effectsInUse, m_doc->PageColors, useCmyk);
787 mode = imageMode;
788 pImage = &scImg;
789 }
790 else
791 pImage = &item->pixm;
792
793 painter->save();
794 if (!item->imageClip.empty())
795 {
796 painter->setupPolygon(&item->imageClip);
797 painter->setClipPath();
798 }
799 painter->setupPolygon(&item->PoLine);
800 painter->setClipPath();
801 if (item->imageFlippedH())
802 {
803 painter->translate(item->width(), 0);
804 painter->scale(-1, 1);
805 }
806 if (item->imageFlippedV())
807 {
808 painter->translate(0, item->height());
809 painter->scale(1, -1);
810 }
811 painter->translate(item->imageXOffset() * item->imageXScale(), item->imageYOffset() * item->imageYScale());
812 painter->rotate(item->imageRotation());
813 painter->scale(imScaleX, imScaleY);
814 if (pImage->imgInfo.lowResType != 0)
815 painter->scale(pImage->imgInfo.lowResScale, pImage->imgInfo.lowResScale);
816 painter->drawImage(pImage, mode);
817 painter->restore();
818 }
819 }
820 }
821
drawItem_Line(PageItem_Line * item,ScPainterExBase * painter,QRect clip)822 void ScPageOutput::drawItem_Line(PageItem_Line* item, ScPainterExBase* painter, QRect clip)
823 {
824 int startArrowIndex = item->startArrowIndex();
825 int endArrowIndex = item->endArrowIndex();
826
827 if (item->NamedLStyle.isEmpty())
828 {
829 QString patternStrokeVal = item->strokePattern();
830 ScPattern *strokePattern = m_doc->checkedPattern(patternStrokeVal);
831 if (strokePattern)
832 {
833 if (item->patternStrokePath)
834 {
835 QPainterPath guidePath = item->PoLine.toQPainterPath(false);
836 guidePath.moveTo(0, 0);
837 guidePath.lineTo(item->width(), 0);
838 drawStrokePattern(item, painter, guidePath);
839 }
840 else
841 {
842 painter->setPattern(strokePattern, item->patternStrokeScaleX, item->patternStrokeScaleY, item->patternStrokeOffsetX, item->patternStrokeOffsetY, item->patternStrokeRotation, item->patternStrokeSkewX, item->patternStrokeSkewY, item->patternStrokeMirrorX, item->patternStrokeMirrorY);
843 painter->setStrokeMode(ScPainterExBase::Pattern);
844 painter->strokePath();
845 }
846 }
847 else if (item->strokeGradientType() > 0)
848 {
849 QString gradientStrokeVal = item->strokeGradient();
850 if ((!gradientStrokeVal.isEmpty()) && (!m_doc->docGradients.contains(gradientStrokeVal)))
851 gradientStrokeVal.clear();
852 if (!(gradientStrokeVal.isEmpty()) && (m_doc->docGradients.contains(gradientStrokeVal)))
853 painter->m_strokeGradient = VGradientEx(m_doc->docGradients[gradientStrokeVal], *m_doc);
854 if (painter->m_strokeGradient.stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient.
855 {
856 if (item->lineColor() != CommonStrings::None)
857 {
858 ScColorShade strokeColor(m_doc->PageColors[item->lineColor()], item->lineShade());
859 painter->setBrush(strokeColor);
860 painter->setStrokeMode(ScPainterExBase::Solid);
861 }
862 else
863 painter->setStrokeMode(ScPainterExBase::None);
864 }
865 else
866 {
867 FPoint fpStart(item->GrStrokeStartX, item->GrStrokeStartY);
868 FPoint fpEnd(item->GrStrokeEndX, item->GrStrokeEndY);
869 FPoint fpFocal(item->GrStrokeFocalX, item->GrStrokeFocalY);
870 painter->setStrokeMode(ScPainterExBase::Gradient);
871 painter->m_strokeGradient = VGradientEx(item->stroke_gradient, *m_doc);
872 if (item->GrTypeStroke == Gradient_Linear)
873 painter->setGradient(VGradientEx::linear, fpStart, fpEnd, fpStart, item->GrStrokeScale, item->GrStrokeSkew);
874 else
875 painter->setGradient(VGradientEx::radial, fpStart, fpEnd, fpFocal, item->GrStrokeScale, item->GrStrokeSkew);
876 }
877 painter->drawLine(FPoint(0, 0), FPoint(item->width(), 0));
878 }
879 else if (item->lineColor() != CommonStrings::None)
880 {
881 ScColorShade scColor(m_doc->PageColors[item->lineColor()], item->lineShade());
882 painter->setStrokeMode(ScPainterExBase::Solid);
883 painter->setPen(scColor, item->lineWidth(), item->PLineArt, item->PLineEnd, item->PLineJoin);
884 if (item->DashValues.count() != 0)
885 painter->setDash(item->DashValues, item->DashOffset);
886 painter->drawLine(FPoint(0, 0), FPoint(item->width(), 0));
887 }
888 }
889 else
890 {
891 painter->setStrokeMode(ScPainterExBase::Solid);
892 multiLine ml = m_doc->docLineStyles[item->NamedLStyle];
893 for (int it = ml.size() - 1; it > -1; it--)
894 {
895 const SingleLine& sl = ml[it];
896 if ((sl.Color != CommonStrings::None) && (sl.Width != 0))
897 {
898 ScColorShade tmp(m_doc->PageColors[sl.Color], sl.Shade);
899 painter->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash),
900 static_cast<Qt::PenCapStyle>(sl.LineEnd),
901 static_cast<Qt::PenJoinStyle>(sl.LineJoin));
902 painter->drawLine(FPoint(0, 0), FPoint(item->width(), 0));
903 }
904 }
905 }
906 if (startArrowIndex != 0)
907 {
908 QTransform arrowTrans;
909 arrowTrans.translate(0, 0);
910 arrowTrans.scale(-1, 1);
911 drawArrow(painter, item, arrowTrans, startArrowIndex);
912 }
913 if (endArrowIndex != 0)
914 {
915 QTransform arrowTrans;
916 arrowTrans.translate(item->width(), 0);
917 drawArrow(painter, item, arrowTrans, endArrowIndex);
918 }
919 }
920
921 class ScPageOutputPainter: public TextLayoutPainter
922 {
923 private:
924 PageItem* m_item;
925 ScPainterExBase* m_painter;
926 ScPageOutput* m_scpage;
927
setupState()928 void setupState()
929 {
930 m_painter->setLineWidth(strokeWidth());
931 ScColorShade fill(m_item->doc()->PageColors[fillColor().color], fillColor().shade);
932 m_painter->setBrush(fill);
933 ScColorShade stroke(m_item->doc()->PageColors[strokeColor().color], strokeColor().shade);
934 m_painter->setPen(stroke, strokeWidth(), Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
935
936 if (matrix() != QTransform())
937 {
938 m_painter->setWorldMatrix(matrix() * m_painter->worldMatrix());
939 }
940 }
941
942 public:
ScPageOutputPainter(PageItem * item,ScPainterExBase * painter,ScPageOutput * scpage)943 ScPageOutputPainter(PageItem* item, ScPainterExBase* painter, ScPageOutput* scpage)
944 : m_item(item)
945 , m_painter(painter)
946 , m_scpage(scpage)
947 {}
948
translate(double xp,double yp)949 void translate(double xp, double yp) override
950 {
951 TextLayoutPainter::translate(xp, yp);
952 m_painter->translate(xp, yp);
953 }
954
save()955 void save() override
956 {
957 TextLayoutPainter::save();
958 m_painter->save();
959 }
960
restore()961 void restore() override
962 {
963 TextLayoutPainter::restore();
964 m_painter->restore();
965 }
966
setScale(double h,double v)967 void setScale(double h, double v) override
968 {
969 TextLayoutPainter::setScale(h, v);
970 m_painter->scale(h, v);
971 }
972
drawGlyph(const GlyphCluster & gc)973 void drawGlyph(const GlyphCluster& gc) override
974 {
975 if (gc.isControlGlyphs())
976 return;
977
978 m_painter->save();
979 bool fr = m_painter->fillRule();
980 int fm = m_painter->fillMode();
981
982 m_painter->setFillRule(false);
983 m_painter->setFillMode(ScPainterExBase::Solid);
984
985 setupState();
986
987 double sizeFactor = fontSize() / 10.0;
988 QVector<FPointArray> outlines = gc.glyphClusterOutline();
989 const QList<GlyphLayout>& glyphs = gc.glyphs();
990 for (int i = 0; i < glyphs.count(); ++i)
991 {
992 const FPointArray& outline = outlines.at(i);
993 const GlyphLayout& gl = glyphs.at(i);
994 m_painter->save();
995 m_painter->translate(gl.xoffset, - (fontSize() * gl.scaleV) + gl.yoffset);
996 m_painter->scale(gl.scaleH * sizeFactor, gl.scaleV * sizeFactor);
997 m_painter->setupPolygon(&outline, true);
998 if (outline.size() > 3)
999 m_painter->fillPath();
1000 m_painter->restore();
1001 m_painter->translate(gl.xadvance * gl.scaleH, 0.0);
1002 }
1003
1004 m_painter->setFillMode(fm);
1005 m_painter->setFillRule(fr);
1006 m_painter->restore();
1007 }
1008
drawGlyphOutline(const GlyphCluster & gc,bool fill)1009 void drawGlyphOutline(const GlyphCluster& gc, bool fill) override
1010 {
1011 if (gc.isControlGlyphs())
1012 return;
1013
1014 if (fill)
1015 drawGlyph(gc);
1016
1017 m_painter->save();
1018 bool fr = m_painter->fillRule();
1019 m_painter->setFillRule(false);
1020
1021 setupState();
1022 double current_x = 0.0;
1023 for (const GlyphLayout& gl : gc.glyphs())
1024 {
1025 m_painter->save();
1026 m_painter->translate(gl.xoffset + current_x, -(fontSize() * gc.scaleV()) + gl.yoffset);
1027
1028 FPointArray outline = font().glyphOutline(gl.glyph);
1029 double scaleH = gl.scaleH * fontSize() / 10.0;
1030 double scaleV = gl.scaleV * fontSize() / 10.0;
1031 QTransform trans;
1032 trans.scale(scaleH, scaleV);
1033 outline.map(trans);
1034 m_painter->setupPolygon(&outline, true);
1035 if (outline.size() > 3)
1036 {
1037 m_painter->setLineWidth(strokeWidth());
1038 m_painter->strokePath();
1039 }
1040 m_painter->restore();
1041 current_x += gl.xadvance * gl.scaleH;
1042 }
1043
1044 m_painter->setFillRule(fr);
1045 m_painter->restore();
1046 }
1047
drawLine(QPointF start,QPointF end)1048 void drawLine(QPointF start, QPointF end) override
1049 {
1050 m_painter->save();
1051 setupState();
1052 m_painter->drawLine(start, end);
1053 m_painter->restore();
1054 }
1055
drawRect(QRectF rect)1056 void drawRect(QRectF rect) override
1057 {
1058 m_painter->save();
1059 setupState();
1060 m_painter->setFillMode(ScPainterExBase::Solid);
1061 m_painter->setStrokeMode(ScPainterExBase::Solid);
1062 m_painter->drawRect(rect.x(), rect.y(), rect.width(), rect.height());
1063 m_painter->restore();
1064 }
1065
drawObject(PageItem * embedded)1066 void drawObject(PageItem* embedded) override
1067 {
1068 QRect cullingArea;
1069 if (!embedded)
1070 return;
1071
1072 m_painter->save();
1073 double pws = embedded->m_lineWidth;
1074
1075 embedded->invalid = true;
1076 m_scpage->drawItem_Pre(embedded, m_painter);
1077
1078 switch (embedded->itemType())
1079 {
1080 case PageItem::ImageFrame:
1081 case PageItem::TextFrame:
1082 case PageItem::LatexFrame:
1083 case PageItem::OSGFrame:
1084 case PageItem::Polygon:
1085 case PageItem::PathText:
1086 case PageItem::Symbol:
1087 case PageItem::Group:
1088 case PageItem::RegularPolygon:
1089 case PageItem::Arc:
1090 case PageItem::Table:
1091 m_scpage->drawItem(embedded, m_painter, cullingArea);
1092 break;
1093 case PageItem::Line:
1094 case PageItem::PolyLine:
1095 case PageItem::Spiral:
1096 embedded->m_lineWidth = pws * qMin(scaleH(), scaleV());
1097 m_scpage->drawItem(embedded, m_painter, cullingArea);
1098 break;
1099 default:
1100 break;
1101 }
1102
1103 embedded->m_lineWidth = pws * qMin(scaleH(), scaleV());
1104 m_scpage->drawItem_Post(embedded, m_painter);
1105 embedded->m_lineWidth = pws;
1106 m_painter->restore();
1107 }
1108 };
1109
drawItem_Polygon(PageItem_Polygon * item,ScPainterExBase * painter,QRect clip)1110 void ScPageOutput::drawItem_Polygon(PageItem_Polygon* item , ScPainterExBase* painter, QRect clip)
1111 {
1112 painter->setupPolygon(&item->PoLine);
1113 fillPath(item, painter, clip);
1114 }
1115
drawItem_PolyLine(PageItem_PolyLine * item,ScPainterExBase * painter,QRect clip)1116 void ScPageOutput::drawItem_PolyLine(PageItem_PolyLine* item, ScPainterExBase* painter, QRect clip)
1117 {
1118 if (item->PoLine.size() < 4)
1119 return;
1120
1121 int startArrowIndex = item->startArrowIndex();
1122 int endArrowIndex = item->endArrowIndex();
1123
1124 if ((item->fillColor() != CommonStrings::None) || (item->GrType != 0))
1125 {
1126 FPointArray cli;
1127 FPoint Start;
1128 bool firstp = true;
1129 for (int n = 0; n < item->PoLine.size()-3; n += 4)
1130 {
1131 if (firstp)
1132 {
1133 Start = item->PoLine.point(n);
1134 firstp = false;
1135 }
1136 if (item->PoLine.isMarker(n))
1137 {
1138 if (n >= 2)
1139 {
1140 cli.addPoint(item->PoLine.point(n - 2));
1141 cli.addPoint(item->PoLine.point(n - 2));
1142 cli.addPoint(Start);
1143 cli.addPoint(Start);
1144 cli.setMarker();
1145 }
1146 firstp = true;
1147 continue;
1148 }
1149 cli.addPoint(item->PoLine.point(n));
1150 cli.addPoint(item->PoLine.point(n+1));
1151 cli.addPoint(item->PoLine.point(n+2));
1152 cli.addPoint(item->PoLine.point(n+3));
1153 }
1154 if (cli.size() > 2)
1155 {
1156 FPoint l1 = cli.point(cli.size()-2);
1157 cli.addPoint(l1);
1158 cli.addPoint(l1);
1159 cli.addPoint(Start);
1160 cli.addPoint(Start);
1161 }
1162 painter->setupPolygon(&cli);
1163 fillPath(item, painter, clip);
1164 }
1165 painter->setupPolygon(&item->PoLine, false);
1166 if (item->NamedLStyle.isEmpty())
1167 {
1168 QString patternStrokeVal = item->strokePattern();
1169 ScPattern *strokePattern = m_doc->checkedPattern(patternStrokeVal);
1170 if (strokePattern)
1171 {
1172 if (item->patternStrokePath)
1173 {
1174 QPainterPath guidePath = item->PoLine.toQPainterPath(false);
1175 guidePath.moveTo(0, 0);
1176 guidePath.lineTo(item->width(), 0);
1177 drawStrokePattern(item, painter, guidePath);
1178 }
1179 else
1180 {
1181 painter->setPattern(strokePattern, item->patternStrokeScaleX, item->patternStrokeScaleY, item->patternStrokeOffsetX, item->patternStrokeOffsetY, item->patternStrokeRotation, item->patternStrokeSkewX, item->patternStrokeSkewY, item->patternStrokeMirrorX, item->patternStrokeMirrorY);
1182 painter->setStrokeMode(ScPainterExBase::Pattern);
1183 painter->strokePath();
1184 }
1185 }
1186 else if (item->strokeGradientType() > 0)
1187 {
1188 QString gradientStrokeVal = item->strokeGradient();
1189 if ((!gradientStrokeVal.isEmpty()) && (!m_doc->docGradients.contains(gradientStrokeVal)))
1190 gradientStrokeVal.clear();
1191 if (!(gradientStrokeVal.isEmpty()) && (m_doc->docGradients.contains(gradientStrokeVal)))
1192 painter->m_strokeGradient = VGradientEx(m_doc->docGradients[gradientStrokeVal], *m_doc);
1193 if (painter->m_strokeGradient.stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient.
1194 {
1195 if (item->lineColor() != CommonStrings::None)
1196 {
1197 ScColorShade strokeColor(m_doc->PageColors[item->lineColor()], item->lineShade());
1198 painter->setBrush(strokeColor);
1199 painter->setStrokeMode(ScPainterExBase::Solid);
1200 }
1201 else
1202 painter->setStrokeMode(ScPainterExBase::None);
1203 }
1204 else
1205 {
1206 FPoint fpStart(item->GrStrokeStartX, item->GrStrokeStartY);
1207 FPoint fpEnd(item->GrStrokeEndX, item->GrStrokeEndY);
1208 FPoint fpFocal(item->GrStrokeFocalX, item->GrStrokeFocalY);
1209 painter->setStrokeMode(ScPainterExBase::Gradient);
1210 painter->m_strokeGradient = VGradientEx(item->stroke_gradient, *m_doc);
1211 if (item->GrTypeStroke == Gradient_Linear)
1212 painter->setGradient(VGradientEx::linear, fpStart, fpEnd, fpStart, item->GrStrokeScale, item->GrStrokeSkew);
1213 else
1214 painter->setGradient(VGradientEx::radial, fpStart, fpEnd, fpFocal, item->GrStrokeScale, item->GrStrokeSkew);
1215 }
1216 painter->strokePath();
1217 }
1218 else if (item->lineColor() != CommonStrings::None)
1219 {
1220 ScColorShade scColor(m_doc->PageColors[item->lineColor()], item->lineShade());
1221 painter->setStrokeMode(ScPainterExBase::Solid);
1222 painter->setPen(scColor, item->lineWidth(), item->PLineArt, item->PLineEnd, item->PLineJoin);
1223 if (item->DashValues.count() != 0)
1224 painter->setDash(item->DashValues, item->DashOffset);
1225 painter->strokePath();
1226 }
1227 }
1228 else
1229 {
1230 multiLine ml = m_doc->docLineStyles[item->NamedLStyle];
1231 for (int it = ml.size() - 1; it > -1; it--)
1232 {
1233 const SingleLine& sl = ml[it];
1234 if (sl.Color != CommonStrings::None)
1235 {
1236 ScColorShade tmp(m_doc->PageColors[sl.Color], sl.Shade);
1237 painter->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash),
1238 static_cast<Qt::PenCapStyle>(sl.LineEnd),
1239 static_cast<Qt::PenJoinStyle>(sl.LineJoin));
1240 painter->strokePath();
1241 }
1242 }
1243 }
1244 if (startArrowIndex != 0)
1245 {
1246 FPoint Start = item->PoLine.point(0);
1247 for (int xx = 1; xx < item->PoLine.size(); xx += 2)
1248 {
1249 FPoint Vector = item->PoLine.point(xx);
1250 if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
1251 {
1252 double r = atan2(Start.y() - Vector.y(), Start.x() - Vector.x()) * (180.0 / M_PI);
1253 QTransform arrowTrans;
1254 arrowTrans.translate(Start.x(), Start.y());
1255 arrowTrans.rotate(r);
1256 drawArrow(painter, item, arrowTrans, startArrowIndex);
1257 break;
1258 }
1259 }
1260 }
1261 if (endArrowIndex != 0)
1262 {
1263 FPoint End = item->PoLine.point(item->PoLine.size()-2);
1264 for (uint xx = item->PoLine.size() - 1; xx > 0; xx -= 2)
1265 {
1266 FPoint Vector = item->PoLine.point(xx);
1267 if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
1268 {
1269 double r = atan2(End.y() - Vector.y(), End.x() - Vector.x()) * (180.0 / M_PI);
1270 QTransform arrowTrans;
1271 arrowTrans.translate(End.x(), End.y());
1272 arrowTrans.rotate(r);
1273 drawArrow(painter, item, arrowTrans, endArrowIndex);
1274 break;
1275 }
1276 }
1277 }
1278 }
1279
drawItem_RegularPolygon(PageItem_RegularPolygon * item,ScPainterExBase * painter,QRect clip)1280 void ScPageOutput::drawItem_RegularPolygon(PageItem_RegularPolygon* item, ScPainterExBase* painter, QRect clip)
1281 {
1282 painter->setupPolygon(&item->PoLine);
1283 painter->fillPath();
1284 }
1285
drawItem_Spiral(PageItem_Spiral * item,ScPainterExBase * painter,QRect clip)1286 void ScPageOutput::drawItem_Spiral(PageItem_Spiral* item, ScPainterExBase* painter, QRect clip)
1287 {
1288 if (item->PoLine.size() < 4)
1289 return;
1290
1291 int startArrowIndex = item->startArrowIndex();
1292 int endArrowIndex = item->endArrowIndex();
1293
1294 if ((item->fillColor() != CommonStrings::None) || (item->GrType != 0))
1295 {
1296 FPointArray cli;
1297 FPoint Start;
1298 bool firstp = true;
1299 for (int n = 0; n < item->PoLine.size()-3; n += 4)
1300 {
1301 if (firstp)
1302 {
1303 Start = item->PoLine.point(n);
1304 firstp = false;
1305 }
1306 if (item->PoLine.isMarker(n))
1307 {
1308 cli.addPoint(item->PoLine.point(n-2));
1309 cli.addPoint(item->PoLine.point(n-2));
1310 cli.addPoint(Start);
1311 cli.addPoint(Start);
1312 cli.setMarker();
1313 firstp = true;
1314 continue;
1315 }
1316 cli.addPoint(item->PoLine.point(n));
1317 cli.addPoint(item->PoLine.point(n+1));
1318 cli.addPoint(item->PoLine.point(n+2));
1319 cli.addPoint(item->PoLine.point(n+3));
1320 }
1321 if (cli.size() > 2)
1322 {
1323 FPoint l1 = cli.point(cli.size()-2);
1324 cli.addPoint(l1);
1325 cli.addPoint(l1);
1326 cli.addPoint(Start);
1327 cli.addPoint(Start);
1328 }
1329 painter->setupPolygon(&cli);
1330 fillPath(item, painter, clip);
1331 }
1332 painter->setupPolygon(&item->PoLine, false);
1333 if (item->NamedLStyle.isEmpty())
1334 {
1335 QString patternStrokeVal = item->strokePattern();
1336 ScPattern *strokePattern = m_doc->checkedPattern(patternStrokeVal);
1337 if (strokePattern)
1338 {
1339 if (item->patternStrokePath)
1340 {
1341 QPainterPath guidePath = item->PoLine.toQPainterPath(false);
1342 guidePath.moveTo(0, 0);
1343 guidePath.lineTo(item->width(), 0);
1344 drawStrokePattern(item, painter, guidePath);
1345 }
1346 else
1347 {
1348 painter->setPattern(strokePattern, item->patternStrokeScaleX, item->patternStrokeScaleY, item->patternStrokeOffsetX, item->patternStrokeOffsetY, item->patternStrokeRotation, item->patternStrokeSkewX, item->patternStrokeSkewY, item->patternStrokeMirrorX, item->patternStrokeMirrorY);
1349 painter->setStrokeMode(ScPainterExBase::Pattern);
1350 painter->strokePath();
1351 }
1352 }
1353 else if (item->strokeGradientType() > 0)
1354 {
1355 QString gradientStrokeVal = item->strokeGradient();
1356 if ((!gradientStrokeVal.isEmpty()) && (!m_doc->docGradients.contains(gradientStrokeVal)))
1357 gradientStrokeVal.clear();
1358 if (!(gradientStrokeVal.isEmpty()) && (m_doc->docGradients.contains(gradientStrokeVal)))
1359 painter->m_strokeGradient = VGradientEx(m_doc->docGradients[gradientStrokeVal], *m_doc);
1360 if (painter->m_strokeGradient.stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient.
1361 {
1362 if (item->lineColor() != CommonStrings::None)
1363 {
1364 ScColorShade strokeColor(m_doc->PageColors[item->lineColor()], item->lineShade());
1365 painter->setBrush(strokeColor);
1366 painter->setStrokeMode(ScPainterExBase::Solid);
1367 }
1368 else
1369 painter->setStrokeMode(ScPainterExBase::None);
1370 }
1371 else
1372 {
1373 FPoint fpStart(item->GrStrokeStartX, item->GrStrokeStartY);
1374 FPoint fpEnd(item->GrStrokeEndX, item->GrStrokeEndY);
1375 FPoint fpFocal(item->GrStrokeFocalX, item->GrStrokeFocalY);
1376 painter->setStrokeMode(ScPainterExBase::Gradient);
1377 painter->m_strokeGradient = VGradientEx(item->stroke_gradient, *m_doc);
1378 if (item->GrTypeStroke == Gradient_Linear)
1379 painter->setGradient(VGradientEx::linear, fpStart, fpEnd, fpStart, item->GrStrokeScale, item->GrStrokeSkew);
1380 else
1381 painter->setGradient(VGradientEx::radial, fpStart, fpEnd, fpFocal, item->GrStrokeScale, item->GrStrokeSkew);
1382 }
1383 painter->strokePath();
1384 }
1385 else if (item->lineColor() != CommonStrings::None)
1386 {
1387 ScColorShade scColor(m_doc->PageColors[item->lineColor()], item->lineShade());
1388 painter->setStrokeMode(ScPainterExBase::Solid);
1389 painter->setPen(scColor, item->lineWidth(), item->PLineArt, item->PLineEnd, item->PLineJoin);
1390 if (item->DashValues.count() != 0)
1391 painter->setDash(item->DashValues, item->DashOffset);
1392 painter->strokePath();
1393 }
1394 }
1395 else
1396 {
1397 multiLine ml = m_doc->docLineStyles[item->NamedLStyle];
1398 for (int it = ml.size() - 1; it > -1; it--)
1399 {
1400 const SingleLine& sl = ml[it];
1401 if (sl.Color != CommonStrings::None)
1402 {
1403 ScColorShade tmp(m_doc->PageColors[sl.Color], sl.Shade);
1404 painter->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash),
1405 static_cast<Qt::PenCapStyle>(sl.LineEnd),
1406 static_cast<Qt::PenJoinStyle>(sl.LineJoin));
1407 painter->strokePath();
1408 }
1409 }
1410 }
1411 if (startArrowIndex != 0)
1412 {
1413 FPoint Start = item->PoLine.point(0);
1414 for (int xx = 1; xx < item->PoLine.size(); xx += 2)
1415 {
1416 FPoint Vector = item->PoLine.point(xx);
1417 if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
1418 {
1419 double r = atan2(Start.y() - Vector.y(), Start.x() - Vector.x()) * (180.0 / M_PI);
1420 QTransform arrowTrans;
1421 arrowTrans.translate(Start.x(), Start.y());
1422 arrowTrans.rotate(r);
1423 drawArrow(painter, item, arrowTrans, startArrowIndex);
1424 break;
1425 }
1426 }
1427 }
1428 if (endArrowIndex != 0)
1429 {
1430 FPoint End = item->PoLine.point(item->PoLine.size()-2);
1431 for (uint xx = item->PoLine.size() - 1; xx > 0; xx -= 2)
1432 {
1433 FPoint Vector = item->PoLine.point(xx);
1434 if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
1435 {
1436 double r = atan2(End.y() - Vector.y(), End.x() - Vector.x()) * (180.0 / M_PI);
1437 QTransform arrowTrans;
1438 arrowTrans.translate(End.x(), End.y());
1439 arrowTrans.rotate(r);
1440 drawArrow(painter, item, arrowTrans, endArrowIndex);
1441 break;
1442 }
1443 }
1444 }
1445 }
1446
drawItem_Table(PageItem_Table * item,ScPainterExBase * painter,QRect clip)1447 void ScPageOutput::drawItem_Table(PageItem_Table* item, ScPainterExBase* painter, QRect clip)
1448 {
1449 painter->save();
1450
1451 // Set the clip path.
1452 painter->setupPolygon(&item->PoLine);
1453 painter->setClipPath();
1454
1455 // Paint the table.
1456 CollapsedTablePainterEx tablePainter(this, item);
1457 tablePainter.paintTable(painter);
1458
1459 painter->restore();
1460 }
1461
drawItem_Text(PageItem * item,ScPainterExBase * painter,QRect cullingArea)1462 void ScPageOutput::drawItem_Text(PageItem* item, ScPainterExBase* painter, QRect cullingArea)
1463 {
1464 if (item->pathTextShowFrame())
1465 {
1466 painter->setupPolygon(&item->PoLine, false);
1467 if (item->NamedLStyle.isEmpty())
1468 {
1469 if (item->lineColor() != CommonStrings::None)
1470 painter->strokePath();
1471 }
1472 else
1473 {
1474 multiLine ml = m_doc->docLineStyles[item->NamedLStyle];
1475 for (int it = ml.size() - 1; it > -1; it--)
1476 {
1477 const SingleLine& sl = ml[it];
1478 if ((sl.Color != CommonStrings::None) && (sl.Width != 0))
1479 {
1480 ScColorShade tmp(m_doc->PageColors[sl.Color], sl.Shade);
1481 painter->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash),
1482 static_cast<Qt::PenCapStyle>(sl.LineEnd),
1483 static_cast<Qt::PenJoinStyle>(sl.LineJoin));
1484 painter->drawLine(FPoint(0, 0), FPoint(item->width(), 0));
1485 }
1486 }
1487 }
1488 }
1489 painter->save();
1490
1491 if ((item->fillColor() != CommonStrings::None) || (item->GrType != 0))
1492 {
1493 painter->setupPolygon(&item->PoLine);
1494 fillPath(item, painter, cullingArea);
1495 }
1496 if ((item->isAnnotation()) && (item->annotation().Type() == Annotation::Button) && (!item->Pfile.isEmpty()) && (item->imageIsAvailable) && (item->imageVisible()) && (item->annotation().UseIcons()))
1497 {
1498 painter->save();
1499 painter->setupPolygon(&item->PoLine);
1500 painter->setClipPath();
1501 painter->scale(item->imageXScale(), item->imageYScale());
1502 painter->translate(static_cast<int>(item->imageXOffset() * item->imageXScale()), static_cast<int>(item->imageYOffset() * item->imageYScale()));
1503 if (!item->pixm.qImage().isNull())
1504 painter->drawImage(&item->pixm, ScPainterExBase::rgbImages);
1505 painter->restore();
1506 }
1507
1508 if (item->isMasterItem())
1509 {
1510 // relayout necessary to get page number ok
1511 item->invalidateLayout();
1512 item->layout();
1513 }
1514
1515 ScPageOutputPainter p(item, painter, this);
1516 item->textLayout.renderBackground(&p);
1517 item->textLayout.render(&p);
1518
1519 painter->restore();
1520 }
1521
drawArrow(ScPainterExBase * painter,PageItem * item,QTransform & arrowTrans,int arrowIndex)1522 void ScPageOutput::drawArrow(ScPainterExBase* painter, PageItem* item, QTransform &arrowTrans, int arrowIndex)
1523 {
1524 FPointArray arrow = m_doc->arrowStyles().at(arrowIndex - 1).points.copy();
1525 if (item->NamedLStyle.isEmpty())
1526 {
1527 if (item->lineWidth() != 0.0)
1528 arrowTrans.scale(item->lineWidth(), item->lineWidth());
1529 }
1530 else
1531 {
1532 multiLine ml = m_doc->docLineStyles[item->NamedLStyle];
1533 if (ml[ml.size() - 1].Width != 0.0)
1534 arrowTrans.scale(ml[ml.size() - 1].Width, ml[ml.size() - 1].Width);
1535 }
1536 arrow.map(arrowTrans);
1537 painter->setupPolygon(&arrow);
1538 if (item->NamedLStyle.isEmpty())
1539 {
1540 if (item->lineColor() != CommonStrings::None)
1541 {
1542 ScColorShade tmp(m_doc->PageColors[item->lineColor()], item->lineShade());
1543 painter->setBrush(tmp);
1544 painter->setBrushOpacity(1.0 - item->lineTransparency());
1545 painter->setLineWidth(0);
1546 painter->setFillMode(ScPainterExBase::Solid);
1547 painter->fillPath();
1548 }
1549 }
1550 else
1551 {
1552 multiLine ml = m_doc->docLineStyles[item->NamedLStyle];
1553 if (ml[0].Color != CommonStrings::None)
1554 {
1555 ScColorShade tmp(m_doc->PageColors[ml[0].Color], ml[0].Shade);
1556 painter->setBrush(tmp);
1557 painter->setLineWidth(0);
1558 painter->setFillMode(ScPainterExBase::Solid);
1559 painter->fillPath();
1560 }
1561 for (int it = ml.size() - 1; it > 0; it--)
1562 {
1563 if (ml[it].Color != CommonStrings::None)
1564 {
1565 ScColorShade tmp(m_doc->PageColors[ml[it].Color], ml[it].Shade);
1566 painter->setPen(tmp, ml[it].Width, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1567 painter->strokePath();
1568 }
1569 }
1570 }
1571 }
1572
drawMarks(ScPage * page,ScPainterExBase * painter,const MarksOptions & options)1573 void ScPageOutput::drawMarks(ScPage* page, ScPainterExBase* painter, const MarksOptions& options)
1574 {
1575 double markLength = options.markLength;
1576 double markOffs = options.markOffset;
1577 double bleedLeft = 0.0, bleedRight = 0.0;
1578 double bleedBottom = options.BleedBottom;
1579 double bleedTop = options.BleedTop;
1580 if (!options.cropMarks && !options.bleedMarks && !options.registrationMarks && !options.colorMarks)
1581 return;
1582 if (m_doc->locationOfPage(page->pageNr()) == LeftPage)
1583 {
1584 bleedRight = options.BleedRight;
1585 bleedLeft = options.BleedLeft;
1586 }
1587 else if (m_doc->locationOfPage(page->pageNr()) == RightPage)
1588 {
1589 bleedRight = options.BleedLeft;
1590 bleedLeft = options.BleedRight;
1591 }
1592 else
1593 {
1594 bleedRight = options.BleedLeft;
1595 bleedLeft = options.BleedLeft;
1596 }
1597 double width = page->width();
1598 double height = page->height();
1599 double offsetX = page->xOffset();
1600 double offsetY = page->yOffset();
1601 QPointF bleedTopLeft(offsetX - bleedLeft, offsetY - bleedTop);
1602 QPointF bleedBottomRight(offsetX + width + bleedRight, offsetY + height + bleedBottom);
1603 QRectF bleedBox(bleedTopLeft, bleedBottomRight);
1604 painter->save();
1605 painter->setLineWidth(0.5);
1606 painter->setPen(ScColorShade(Qt::black, 100), 0.5, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1607 if (options.cropMarks)
1608 {
1609 FPoint start, end;
1610 double left = offsetX, right = offsetX + width;
1611 double bottom = offsetY + height, top = offsetY;
1612 drawBoxMarks(painter, QRectF(QPointF(left, top), QPointF(right, bottom)), bleedBox, markOffs, markLength);
1613 }
1614 if (options.bleedMarks)
1615 {
1616 FPoint start, end;
1617 double left = offsetX - bleedLeft, right = offsetX + width + bleedRight;
1618 double bottom = offsetY + height + bleedBottom, top = offsetY - bleedTop;
1619 drawBoxMarks(painter, QRectF(QPointF(left, top), QPointF(right, bottom)), bleedBox, markOffs, markLength);
1620 }
1621 if (options.registrationMarks)
1622 {
1623 double posX = (2* offsetX + width) / 2.0 - 7.0;
1624 double posY = (offsetY + height + bleedBottom + markOffs + 3.0);
1625 painter->save();
1626 painter->translate(posX, posY);
1627 drawRegistrationCross(painter);
1628 painter->restore();
1629 posX = (2 * offsetX + width) / 2.0 - 7.0;
1630 posY = (offsetY - bleedTop - markOffs - 17);
1631 painter->save();
1632 painter->translate(posX, posY);
1633 drawRegistrationCross(painter);
1634 painter->restore();
1635
1636 posX = (offsetX - bleedLeft - markOffs - 17);
1637 posY = (2 * offsetY + height) / 2.0 - 7.0;
1638 painter->save();
1639 painter->translate(posX, posY);
1640 drawRegistrationCross(painter);
1641 painter->restore();
1642 posX = (offsetX + width + bleedRight + markOffs + 3.0);
1643 posY = (2 * offsetY + height) / 2.0 - 7.0;
1644 painter->save();
1645 painter->translate(posX, posY);
1646 drawRegistrationCross(painter);
1647 painter->restore();
1648 }
1649 if (options.colorMarks)
1650 {
1651 int shade = 100;
1652 double startX = offsetX + 6.0;
1653 double startY = offsetY - bleedTop - markOffs - 16.0;
1654 ScColorShade strokecolor(ScColor(0, 0, 0, 255), 100);
1655 painter->setPen(strokecolor, 0.5, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
1656 painter->setFillMode(ScPainterExBase::Solid);
1657 for (int i = 0; i < 11; i++)
1658 {
1659 ScColorShade fillcolor(ScColor(0, 0, 0, 255), shade);
1660 painter->setBrush(fillcolor);
1661 painter->drawRect(startX + i * 14, startY, 14, 14);
1662 shade -= 10;
1663 }
1664 startX = offsetX + width - 20.0;
1665 painter->setBrush(ScColorShade(ScColor(0, 0, 0, 255), 50));
1666 painter->drawRect(startX, startY, 14, 14);
1667 startX -= 14;
1668 painter->setBrush(ScColorShade(ScColor(0, 0, 255, 0), 50));
1669 painter->drawRect(startX, startY, 14, 14);
1670 startX -= 14;
1671 painter->setBrush(ScColorShade(ScColor(0, 255, 0, 0), 50));
1672 painter->drawRect(startX, startY, 14, 14);
1673 startX -= 14;
1674 painter->setBrush(ScColorShade(ScColor(255, 0, 0, 0), 50));
1675 painter->drawRect(startX, startY, 14, 14);
1676 startX -= 14;
1677 painter->setBrush(ScColorShade(ScColor(255, 255, 0, 0), 100));
1678 painter->drawRect(startX, startY, 14, 14);
1679 startX -= 14;
1680 painter->setBrush(ScColorShade(ScColor(255, 0, 255, 0), 100));
1681 painter->drawRect(startX, startY, 14, 14);
1682 startX -= 14;
1683 painter->setBrush(ScColorShade(ScColor(0, 255, 255, 0), 100));
1684 painter->drawRect(startX, startY, 14, 14);
1685 startX -= 14;
1686 painter->setBrush(ScColorShade(ScColor(0, 0, 0, 255), 100));
1687 painter->drawRect(startX, startY, 14, 14);
1688 startX -= 14;
1689 painter->setBrush(ScColorShade(ScColor(0, 0, 255, 0), 100));
1690 painter->drawRect(startX, startY, 14, 14);
1691 startX -= 14;
1692 painter->setBrush(ScColorShade(ScColor(0, 255, 0, 0), 100));
1693 painter->drawRect(startX, startY, 14, 14);
1694 startX -= 14;
1695 painter->setBrush(ScColorShade(ScColor(255, 0, 0, 0), 100));
1696 painter->drawRect(startX, startY, 14, 14);
1697 }
1698 painter->restore();
1699 }
1700
drawBoxMarks(ScPainterExBase * painter,const QRectF & box,const QRectF & bleedBox,double offset,double markSize)1701 void ScPageOutput::drawBoxMarks(ScPainterExBase* painter, const QRectF& box, const QRectF& bleedBox, double offset , double markSize)
1702 {
1703 FPoint start, end;
1704 double left = box.left(), right = box.right();
1705 double bottom = box.bottom(), top = box.top();
1706 double bleedLeft = bleedBox.left(), bleedRight = bleedBox.right();
1707 double bleedBottom = bleedBox.bottom(), bleedTop = bleedBox.top();
1708 // Top Left
1709 start.setXY(bleedLeft - offset, top);
1710 end.setXY (bleedLeft - offset - markSize, top);
1711 painter->drawLine(start, end);
1712 start.setXY(left, bleedTop - offset);
1713 end.setXY (left, bleedTop - offset - markSize);
1714 painter->drawLine(start, end);
1715 // Top Right
1716 start.setXY(bleedRight + offset, top);
1717 end.setXY (bleedRight + offset + markSize, top);
1718 painter->drawLine(start, end);
1719 start.setXY(right, bleedTop - offset);
1720 end.setXY (right, bleedTop - offset - markSize);
1721 painter->drawLine(start, end);
1722 // Bottom Left
1723 start.setXY(bleedLeft - offset, bottom);
1724 end.setXY (bleedLeft - offset - markSize, bottom);
1725 painter->drawLine(start, end);
1726 start.setXY(left, bleedBottom + offset);
1727 end.setXY (left, bleedBottom + offset + markSize);
1728 painter->drawLine(start, end);
1729 // Bottom Right
1730 start.setXY(bleedRight + offset, bottom);
1731 end.setXY (bleedRight + offset + markSize, bottom);
1732 painter->drawLine(start, end);
1733 start.setXY(right, bleedBottom + offset);
1734 end.setXY (right, bleedBottom + offset + markSize);
1735 painter->drawLine(start, end);
1736 }
1737
drawRegistrationCross(ScPainterExBase * painter)1738 void ScPageOutput::drawRegistrationCross(ScPainterExBase* painter)
1739 {
1740 painter->save();
1741
1742 painter->newPath();
1743 painter->moveTo(0.0, 7.0);
1744 painter->lineTo(14.0, 7.0);
1745 painter->strokePath();
1746
1747 painter->newPath();
1748 painter->moveTo(7.0, 0.0);
1749 painter->lineTo(7.0, 14.0);
1750 painter->strokePath();
1751
1752 painter->newPath();
1753 painter->moveTo(13.0, 7.0);
1754 painter->curveTo(FPoint(13.0, 10.31383), FPoint(10.31383, 13.0), FPoint(7.0, 13.0));
1755 painter->curveTo(FPoint(3.68629, 13.0) , FPoint(1.0, 10.31383) , FPoint(1.0, 7.0));
1756 painter->curveTo(FPoint(1.0, 3.68629) , FPoint(3.68629, 1.0) , FPoint(7.0, 1.0));
1757 painter->curveTo(FPoint(10.31383, 1.0) , FPoint(13.0, 3.68629) , FPoint(13.0, 7.0));
1758 painter->strokePath();
1759
1760 painter->newPath();
1761 painter->moveTo(10.5, 7.0);
1762 painter->curveTo(FPoint(10.5, 8.93307), FPoint(8.93307, 10.5), FPoint(7.0, 10.5));
1763 painter->curveTo(FPoint(5.067, 10.5) , FPoint(3.5, 8.93307) , FPoint(3.5, 7.0));
1764 painter->curveTo(FPoint(3.5, 5.067) , FPoint(5.067, 3.5) , FPoint(7.0, 3.5));
1765 painter->curveTo(FPoint(8.93307, 3.5) , FPoint(10.5, 5.067) , FPoint(10.5, 7.0));
1766 painter->strokePath();
1767
1768 painter->restore();
1769 }
1770
fillPath(PageItem * item,ScPainterExBase * painter,QRect clip)1771 void ScPageOutput::fillPath(PageItem* item, ScPainterExBase* painter, QRect clip)
1772 {
1773 if (painter->fillMode() == ScPainterExBase::Pattern && !painter->hasCapability(ScPainterExBase::patterns))
1774 drawPattern(item, painter, clip);
1775 else
1776 painter->fillPath();
1777 }
1778
strokePath(PageItem * item,ScPainterExBase * painter,QRect clip)1779 void ScPageOutput::strokePath(PageItem* item, ScPainterExBase* painter, QRect clip)
1780 {
1781 painter->strokePath();
1782 }
1783