Rev 16764 | Rev 16767 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
16729 | fschmid | 1 | #include "slaoutput.h" |
2 | #include <GlobalParams.h> |
||
3 | #include <QFile> |
||
4 | #include "commonstrings.h" |
||
5 | #include "loadsaveplugin.h" |
||
6 | #include "sccolorengine.h" |
||
7 | #include "util.h" |
||
8 | #include "util_math.h" |
||
9 | |||
10 | |||
11 | SlaOutputDev::SlaOutputDev(ScribusDoc* doc, QList<PageItem*> *Elements, QStringList *importedColors, int flags) |
||
12 | { |
||
13 | m_doc = doc; |
||
14 | m_Elements = Elements; |
||
15 | m_groupStack.clear(); |
||
16732 | fschmid | 16 | pushGroup(); |
16729 | fschmid | 17 | m_clipStack.clear(); |
18 | m_currentMask = ""; |
||
19 | m_importedColors = importedColors; |
||
20 | CurrColorStroke = "Black"; |
||
21 | CurrColorFill = "Black"; |
||
22 | Coords = ""; |
||
23 | pathIsClosed = false; |
||
24 | tmpSel = new Selection(m_doc, false); |
||
25 | grStackDepth = 0; |
||
26 | firstLayer = true; |
||
27 | layerNum = 1; |
||
28 | importerFlags = flags; |
||
29 | currentLayer = m_doc->activeLayer(); |
||
30 | xref = NULL; |
||
31 | m_fontEngine = 0; |
||
32 | m_font = 0; |
||
33 | firstPage = true; |
||
34 | pagecount = 1; |
||
35 | } |
||
36 | |||
37 | SlaOutputDev::~SlaOutputDev() |
||
38 | { |
||
39 | m_groupStack.clear(); |
||
40 | tmpSel->clear(); |
||
41 | delete tmpSel; |
||
42 | delete m_fontEngine; |
||
43 | } |
||
44 | |||
45 | |||
46 | void SlaOutputDev::startDoc(XRef *xrefA, Catalog *catA) |
||
47 | { |
||
48 | xref = xrefA; |
||
49 | catalog = catA; |
||
50 | firstPage = true; |
||
51 | pagecount = 1; |
||
52 | m_fontEngine = new SplashFontEngine( |
||
53 | #if HAVE_T1LIB_H |
||
54 | globalParams->getEnableT1lib(), |
||
55 | #endif |
||
56 | #if HAVE_FREETYPE_H |
||
57 | globalParams->getEnableFreeType(), |
||
58 | true, |
||
59 | true, |
||
60 | #endif |
||
61 | true); |
||
62 | } |
||
63 | |||
64 | void SlaOutputDev::startPage(int pageNum, GfxState *state) |
||
65 | { |
||
66 | // qDebug() << "starting page" << pageNum; |
||
67 | if (firstPage) |
||
68 | firstPage = false; |
||
69 | else |
||
70 | { |
||
71 | if (importerFlags & LoadSavePlugin::lfCreateDoc) |
||
72 | { |
||
73 | m_doc->addPage(pagecount); |
||
74 | m_doc->view()->addPage(pagecount, true); |
||
75 | pagecount++; |
||
76 | } |
||
77 | } |
||
78 | // qDebug() << "page size =" << pageSize; |
||
79 | } |
||
80 | |||
81 | void SlaOutputDev::endPage() |
||
82 | { |
||
83 | // qDebug() << "ending page"; |
||
84 | } |
||
85 | |||
86 | void SlaOutputDev::saveState(GfxState *state) |
||
87 | { |
||
88 | // qDebug() << "saveState" << grStackDepth; |
||
89 | grStackDepth++; |
||
90 | } |
||
91 | |||
92 | void SlaOutputDev::restoreState(GfxState *state) |
||
93 | { |
||
94 | // qDebug() << "restoreState" << grStackDepth; |
||
95 | grStackDepth--; |
||
96 | if (m_groupStack.count() != 0) |
||
97 | m_groupStack.top().maskName = ""; |
||
98 | if (m_clipStack.count() != 0) |
||
99 | { |
||
100 | while (m_clipStack.top().grStackDepth > grStackDepth) |
||
101 | { |
||
102 | clipEntry clp = m_clipStack.pop(); |
||
103 | PageItem *ite = clp.ClipItem; |
||
104 | if (m_groupStack.count() != 0) |
||
105 | { |
||
106 | groupEntry gElements = m_groupStack.pop(); |
||
107 | if (gElements.Items.count() > 0) |
||
108 | { |
||
109 | for (int d = 0; d < gElements.Items.count(); d++) |
||
110 | { |
||
111 | m_Elements->removeAll(gElements.Items.at(d)); |
||
112 | } |
||
113 | m_doc->groupObjectsToItem(ite, gElements.Items); |
||
114 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
115 | ite->setFillBlendmode(getBlendMode(state)); |
||
116 | } |
||
117 | else |
||
118 | { |
||
119 | m_Elements->removeAll(ite); |
||
120 | m_doc->Items->removeAll(ite); |
||
121 | m_groupStack.top().Items.removeAll(ite); |
||
122 | } |
||
123 | } |
||
124 | if (m_clipStack.count() == 0) |
||
125 | break; |
||
126 | } |
||
127 | } |
||
128 | } |
||
16764 | fschmid | 129 | /* |
16729 | fschmid | 130 | void SlaOutputDev::updateFillColor(GfxState *state) |
131 | { |
||
16746 | fschmid | 132 | int shade = 100; |
133 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
16729 | fschmid | 134 | } |
16764 | fschmid | 135 | */ |
16729 | fschmid | 136 | void SlaOutputDev::beginTransparencyGroup(GfxState *state, double *bbox, GfxColorSpace * /*blendingColorSpace*/, GBool /*isolated*/, GBool /*knockout*/, GBool forSoftMask) |
137 | { |
||
138 | // qDebug() << "Start Group"; |
||
16732 | fschmid | 139 | pushGroup("", forSoftMask); |
16729 | fschmid | 140 | } |
141 | |||
142 | void SlaOutputDev::endTransparencyGroup(GfxState *state) |
||
143 | { |
||
144 | // qDebug() << "End Group"; |
||
145 | if (m_groupStack.count() != 0) |
||
146 | { |
||
147 | groupEntry gElements = m_groupStack.pop(); |
||
148 | tmpSel->clear(); |
||
149 | if (gElements.Items.count() > 0) |
||
150 | { |
||
151 | for (int dre = 0; dre < gElements.Items.count(); ++dre) |
||
152 | { |
||
153 | tmpSel->addItem(gElements.Items.at(dre), true); |
||
154 | m_Elements->removeAll(gElements.Items.at(dre)); |
||
155 | } |
||
156 | PageItem *ite = m_doc->groupObjectsSelection(tmpSel); |
||
157 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
158 | ite->setFillBlendmode(getBlendMode(state)); |
||
159 | if (gElements.forSoftMask) |
||
160 | { |
||
161 | ScPattern pat = ScPattern(); |
||
162 | pat.setDoc(m_doc); |
||
163 | m_doc->DoDrawing = true; |
||
164 | pat.pattern = ite->DrawObj_toImage(qMax(ite->width(), ite->height())); |
||
165 | pat.xoffset = 0; |
||
166 | pat.yoffset = 0; |
||
167 | m_doc->DoDrawing = false; |
||
168 | pat.width = ite->width(); |
||
169 | pat.height = ite->height(); |
||
170 | pat.items.append(ite); |
||
171 | m_doc->Items->removeAll(ite); |
||
172 | QString id = QString("Pattern_from_PDF_%1S").arg(m_doc->docPatterns.count() + 1); |
||
173 | m_doc->addPattern(id, pat); |
||
174 | m_currentMask = id; |
||
175 | tmpSel->clear(); |
||
176 | return; |
||
177 | } |
||
178 | else |
||
179 | { |
||
180 | for (int as = 0; as < tmpSel->count(); ++as) |
||
181 | { |
||
182 | m_Elements->append(tmpSel->itemAt(as)); |
||
183 | } |
||
184 | } |
||
185 | if (m_groupStack.count() != 0) |
||
16732 | fschmid | 186 | applyMask(ite); |
16729 | fschmid | 187 | } |
188 | if (m_groupStack.count() != 0) |
||
189 | { |
||
190 | for (int as = 0; as < tmpSel->count(); ++as) |
||
191 | { |
||
192 | m_groupStack.top().Items.append(tmpSel->itemAt(as)); |
||
193 | } |
||
194 | } |
||
195 | tmpSel->clear(); |
||
196 | } |
||
197 | } |
||
198 | |||
16732 | fschmid | 199 | void SlaOutputDev::setSoftMask(GfxState * /*state*/, double * /*bbox*/, GBool alpha, Function *transferFunc, GfxColor * /*backdropColor*/) |
16729 | fschmid | 200 | { |
201 | if (m_groupStack.count() != 0) |
||
202 | { |
||
16732 | fschmid | 203 | double lum = 0; |
204 | double lum2 = 0; |
||
205 | if (transferFunc) |
||
206 | transferFunc->transform(&lum, &lum2); |
||
207 | else |
||
208 | lum2 = lum; |
||
209 | if (lum == lum2) |
||
210 | m_groupStack.top().inverted = false; |
||
211 | else |
||
212 | m_groupStack.top().inverted = true; |
||
213 | // qDebug() << "Inverted Softmask" << m_groupStack.top().inverted; |
||
16729 | fschmid | 214 | m_groupStack.top().maskName = m_currentMask; |
215 | m_groupStack.top().alpha = alpha; |
||
216 | } |
||
217 | } |
||
218 | |||
219 | void SlaOutputDev::clearSoftMask(GfxState * /*state*/) |
||
220 | { |
||
221 | if (m_groupStack.count() != 0) |
||
222 | { |
||
223 | m_groupStack.top().maskName = ""; |
||
224 | } |
||
225 | } |
||
226 | |||
227 | void SlaOutputDev::clip(GfxState *state) |
||
228 | { |
||
229 | // qDebug() << "Clip"; |
||
230 | double *ctm; |
||
231 | ctm = state->getCTM(); |
||
232 | QString output = convertPath(state->getPath()); |
||
233 | FPointArray out; |
||
234 | out.parseSVG(output); |
||
235 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
236 | out.map(m_ctm); |
||
237 | double xmin, ymin, xmax, ymax; |
||
238 | state->getClipBBox(&xmin, &ymin, &xmax, &ymax); |
||
239 | QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); |
||
240 | crect = crect.normalized(); |
||
241 | int z = m_doc->itemAdd(PageItem::Group, PageItem::Rectangle, crect.x() + m_doc->currentPage()->xOffset(), crect.y() + m_doc->currentPage()->yOffset(), crect.width(), crect.height(), 0, CommonStrings::None, CommonStrings::None, true); |
||
242 | PageItem *ite = m_doc->Items->at(z); |
||
243 | FPoint wh(getMinClipF(&out)); |
||
244 | out.translate(-wh.x(), -wh.y()); |
||
245 | ite->PoLine = out.copy(); //FIXME: try to avoid copy if FPointArray when properly shared |
||
246 | ite->ClipEdited = true; |
||
247 | ite->FrameType = 3; |
||
16744 | fschmid | 248 | ite->setFillEvenOdd(false); |
16729 | fschmid | 249 | ite->Clip = FlattenPath(ite->PoLine, ite->Segments); |
250 | ite->ContourLine = ite->PoLine.copy(); |
||
251 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
252 | m_doc->AdjustItemSize(ite); |
||
253 | m_Elements->append(ite); |
||
254 | if (m_groupStack.count() != 0) |
||
255 | { |
||
256 | m_groupStack.top().Items.append(ite); |
||
16732 | fschmid | 257 | applyMask(ite); |
16729 | fschmid | 258 | } |
259 | clipEntry clp; |
||
260 | clp.ClipCoords = out.copy(); |
||
261 | clp.ClipItem = ite; |
||
262 | clp.grStackDepth = grStackDepth; |
||
263 | m_clipStack.push(clp); |
||
264 | m_doc->GroupCounter++; |
||
16732 | fschmid | 265 | pushGroup(); |
16729 | fschmid | 266 | } |
267 | |||
268 | void SlaOutputDev::eoClip(GfxState *state) |
||
269 | { |
||
270 | // qDebug() << "EoClip"; |
||
271 | double *ctm; |
||
272 | ctm = state->getCTM(); |
||
273 | QString output = convertPath(state->getPath()); |
||
274 | FPointArray out; |
||
275 | out.parseSVG(output); |
||
276 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
277 | out.map(m_ctm); |
||
278 | double xmin, ymin, xmax, ymax; |
||
279 | state->getClipBBox(&xmin, &ymin, &xmax, &ymax); |
||
280 | QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); |
||
281 | crect = crect.normalized(); |
||
282 | int z = m_doc->itemAdd(PageItem::Group, PageItem::Rectangle, crect.x() + m_doc->currentPage()->xOffset(), crect.y() + m_doc->currentPage()->yOffset(), crect.width(), crect.height(), 0, CommonStrings::None, CommonStrings::None, true); |
||
283 | PageItem *ite = m_doc->Items->at(z); |
||
284 | FPoint wh(getMinClipF(&out)); |
||
285 | out.translate(-wh.x(), -wh.y()); |
||
286 | ite->PoLine = out.copy(); //FIXME: try to avoid copy if FPointArray when properly shared |
||
287 | ite->ClipEdited = true; |
||
288 | ite->FrameType = 3; |
||
16744 | fschmid | 289 | ite->setFillEvenOdd(true); |
16729 | fschmid | 290 | ite->Clip = FlattenPath(ite->PoLine, ite->Segments); |
291 | ite->ContourLine = ite->PoLine.copy(); |
||
292 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
293 | m_doc->AdjustItemSize(ite); |
||
294 | m_Elements->append(ite); |
||
295 | if (m_groupStack.count() != 0) |
||
296 | { |
||
297 | m_groupStack.top().Items.append(ite); |
||
16732 | fschmid | 298 | applyMask(ite); |
16729 | fschmid | 299 | } |
300 | clipEntry clp; |
||
301 | clp.ClipCoords = out.copy(); |
||
302 | clp.ClipItem = ite; |
||
303 | clp.grStackDepth = grStackDepth; |
||
304 | m_clipStack.push(clp); |
||
305 | m_doc->GroupCounter++; |
||
16732 | fschmid | 306 | pushGroup(); |
16729 | fschmid | 307 | } |
308 | |||
309 | void SlaOutputDev::stroke(GfxState *state) |
||
310 | { |
||
311 | // qDebug() << "Stroke"; |
||
312 | double *ctm; |
||
313 | ctm = state->getCTM(); |
||
314 | double xCoor = m_doc->currentPage()->xOffset(); |
||
315 | double yCoor = m_doc->currentPage()->yOffset(); |
||
16746 | fschmid | 316 | int shade = 100; |
317 | CurrColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &shade); |
||
16729 | fschmid | 318 | QString output = convertPath(state->getPath()); |
319 | getPenState(state); |
||
320 | if ((m_Elements->count() != 0) && (output == Coords)) // Path is the same as in last fill |
||
321 | { |
||
322 | PageItem* ite = m_Elements->at(m_Elements->count()-1); |
||
323 | ite->setLineColor(CurrColorStroke); |
||
16746 | fschmid | 324 | ite->setLineShade(shade); |
16729 | fschmid | 325 | ite->setLineEnd(PLineEnd); |
326 | ite->setLineJoin(PLineJoin); |
||
327 | ite->setLineWidth(state->getTransformedLineWidth()); |
||
328 | ite->setDashes(DashValues); |
||
329 | ite->setDashOffset(DashOffset); |
||
330 | ite->setLineTransparency(1.0 - state->getStrokeOpacity()); |
||
331 | } |
||
332 | else |
||
333 | { |
||
334 | FPointArray out; |
||
335 | out.parseSVG(output); |
||
336 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
337 | out.map(m_ctm); |
||
338 | FPoint wh = out.WidthHeight(); |
||
339 | if ((out.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0))) |
||
340 | { |
||
341 | int z; |
||
342 | if (pathIsClosed) |
||
343 | z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, state->getTransformedLineWidth(), CommonStrings::None, CurrColorStroke, true); |
||
344 | else |
||
345 | z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, state->getTransformedLineWidth(), CommonStrings::None, CurrColorStroke, true); |
||
346 | PageItem* ite = m_doc->Items->at(z); |
||
347 | ite->PoLine = out.copy(); |
||
348 | ite->ClipEdited = true; |
||
349 | ite->FrameType = 3; |
||
16746 | fschmid | 350 | ite->setLineShade(shade); |
16729 | fschmid | 351 | ite->setLineTransparency(1.0 - state->getStrokeOpacity()); |
352 | ite->setLineBlendmode(getBlendMode(state)); |
||
353 | ite->setLineEnd(PLineEnd); |
||
354 | ite->setLineJoin(PLineJoin); |
||
355 | ite->setDashes(DashValues); |
||
356 | ite->setDashOffset(DashOffset); |
||
357 | ite->setWidthHeight(wh.x(),wh.y()); |
||
358 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
359 | m_doc->AdjustItemSize(ite); |
||
360 | m_Elements->append(ite); |
||
361 | if (m_groupStack.count() != 0) |
||
362 | m_groupStack.top().Items.append(ite); |
||
363 | } |
||
364 | } |
||
365 | } |
||
366 | |||
367 | void SlaOutputDev::fill(GfxState *state) |
||
368 | { |
||
369 | // qDebug() << "Fill"; |
||
370 | double *ctm; |
||
371 | ctm = state->getCTM(); |
||
372 | double xCoor = m_doc->currentPage()->xOffset(); |
||
373 | double yCoor = m_doc->currentPage()->yOffset(); |
||
16746 | fschmid | 374 | int shade = 100; |
375 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
16729 | fschmid | 376 | FPointArray out; |
377 | QString output = convertPath(state->getPath()); |
||
378 | out.parseSVG(output); |
||
379 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
380 | out.map(m_ctm); |
||
381 | Coords = output; |
||
382 | FPoint wh = out.WidthHeight(); |
||
383 | if ((out.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0))) |
||
384 | { |
||
385 | int z; |
||
386 | if (pathIsClosed) |
||
387 | z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CurrColorFill, CommonStrings::None, true); |
||
388 | else |
||
389 | z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CurrColorFill, CommonStrings::None, true); |
||
390 | PageItem* ite = m_doc->Items->at(z); |
||
391 | ite->PoLine = out.copy(); |
||
392 | ite->ClipEdited = true; |
||
393 | ite->FrameType = 3; |
||
16746 | fschmid | 394 | ite->setFillShade(shade); |
16729 | fschmid | 395 | ite->setLineShade(100); |
396 | ite->setFillEvenOdd(false); |
||
397 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
398 | ite->setFillBlendmode(getBlendMode(state)); |
||
399 | ite->setLineEnd(PLineEnd); |
||
400 | ite->setLineJoin(PLineJoin); |
||
401 | ite->setWidthHeight(wh.x(),wh.y()); |
||
402 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
403 | m_doc->AdjustItemSize(ite); |
||
404 | m_Elements->append(ite); |
||
405 | if (m_groupStack.count() != 0) |
||
406 | { |
||
407 | m_groupStack.top().Items.append(ite); |
||
16732 | fschmid | 408 | applyMask(ite); |
16729 | fschmid | 409 | } |
410 | } |
||
411 | } |
||
412 | |||
413 | void SlaOutputDev::eoFill(GfxState *state) |
||
414 | { |
||
415 | // qDebug() << "EoFill"; |
||
416 | double *ctm; |
||
417 | ctm = state->getCTM(); |
||
418 | double xCoor = m_doc->currentPage()->xOffset(); |
||
419 | double yCoor = m_doc->currentPage()->yOffset(); |
||
16746 | fschmid | 420 | int shade = 100; |
421 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
16729 | fschmid | 422 | FPointArray out; |
423 | QString output = convertPath(state->getPath()); |
||
424 | out.parseSVG(output); |
||
425 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
426 | out.map(m_ctm); |
||
427 | Coords = output; |
||
428 | FPoint wh = out.WidthHeight(); |
||
429 | if ((out.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0))) |
||
430 | { |
||
431 | int z; |
||
432 | if (pathIsClosed) |
||
433 | z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CurrColorFill, CommonStrings::None, true); |
||
434 | else |
||
435 | z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CurrColorFill, CommonStrings::None, true); |
||
436 | PageItem* ite = m_doc->Items->at(z); |
||
437 | ite->PoLine = out.copy(); |
||
438 | ite->ClipEdited = true; |
||
439 | ite->FrameType = 3; |
||
16746 | fschmid | 440 | ite->setFillShade(shade); |
16729 | fschmid | 441 | ite->setLineShade(100); |
442 | ite->setFillEvenOdd(true); |
||
443 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
444 | ite->setFillBlendmode(getBlendMode(state)); |
||
445 | ite->setLineEnd(PLineEnd); |
||
446 | ite->setLineJoin(PLineJoin); |
||
447 | ite->setWidthHeight(wh.x(),wh.y()); |
||
448 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
449 | m_doc->AdjustItemSize(ite); |
||
450 | m_Elements->append(ite); |
||
451 | if (m_groupStack.count() != 0) |
||
452 | { |
||
453 | m_groupStack.top().Items.append(ite); |
||
16732 | fschmid | 454 | applyMask(ite); |
16729 | fschmid | 455 | } |
456 | } |
||
457 | } |
||
458 | |||
459 | GBool SlaOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading, double tMin, double tMax) |
||
460 | { |
||
461 | double GrStartX; |
||
462 | double GrStartY; |
||
463 | double GrEndX; |
||
464 | double GrEndY; |
||
16746 | fschmid | 465 | int shade = 100; |
16729 | fschmid | 466 | Function *func = shading->getFunc(0); |
467 | VGradient FillGradient = VGradient(VGradient::linear); |
||
468 | FillGradient.clearStops(); |
||
469 | GfxColorSpace *color_space = shading->getColorSpace(); |
||
470 | if (func->getType() == 3) |
||
471 | { |
||
472 | StitchingFunction *stitchingFunc = (StitchingFunction*)func; |
||
473 | double *bounds = stitchingFunc->getBounds(); |
||
474 | int num_funcs = stitchingFunc->getNumFuncs(); |
||
475 | // Add stops from all the stitched functions |
||
476 | for ( int i = 0 ; i < num_funcs ; i++ ) |
||
477 | { |
||
478 | GfxColor temp; |
||
479 | ((GfxAxialShading*)shading)->getColor(bounds[i], &temp); |
||
16746 | fschmid | 480 | QString stopColor = getColor(color_space, &temp, &shade); |
481 | FillGradient.addStop( ScColorEngine::getRGBColor(m_doc->PageColors[stopColor], m_doc), bounds[i], 0.5, 1.0, stopColor, shade ); |
||
16729 | fschmid | 482 | if (i == num_funcs - 1) |
483 | { |
||
484 | ((GfxAxialShading*)shading)->getColor(bounds[i+1], &temp); |
||
16746 | fschmid | 485 | QString stopColor = getColor(color_space, &temp, &shade); |
486 | FillGradient.addStop( ScColorEngine::getRGBColor(m_doc->PageColors[stopColor], m_doc), bounds[i+1], 0.5, 1.0, stopColor, shade ); |
||
16729 | fschmid | 487 | } |
488 | } |
||
489 | } |
||
490 | else if (func->getType() == 2) |
||
491 | { |
||
492 | GfxColor stop1; |
||
493 | ((GfxAxialShading*)shading)->getColor(0.0, &stop1); |
||
16746 | fschmid | 494 | QString stopColor1 = getColor(color_space, &stop1, &shade); |
495 | FillGradient.addStop( ScColorEngine::getRGBColor(m_doc->PageColors[stopColor1], m_doc), 0.0, 0.5, 1.0, stopColor1, shade ); |
||
16729 | fschmid | 496 | GfxColor stop2; |
497 | ((GfxAxialShading*)shading)->getColor(1.0, &stop2); |
||
16746 | fschmid | 498 | QString stopColor2 = getColor(color_space, &stop2, &shade); |
499 | FillGradient.addStop( ScColorEngine::getRGBColor(m_doc->PageColors[stopColor2], m_doc), 1.0, 0.5, 1.0, stopColor2, shade ); |
||
16729 | fschmid | 500 | } |
501 | ((GfxAxialShading*)shading)->getCoords(&GrStartX, &GrStartY, &GrEndX, &GrEndY); |
||
502 | double xmin, ymin, xmax, ymax; |
||
503 | // get the clip region bbox |
||
504 | state->getClipBBox(&xmin, &ymin, &xmax, &ymax); |
||
505 | QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); |
||
506 | crect = crect.normalized(); |
||
507 | double *ctm; |
||
508 | ctm = state->getCTM(); |
||
509 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
510 | FPointArray gr; |
||
511 | gr.addPoint(GrStartX, GrStartY); |
||
512 | gr.addPoint(GrEndX, GrEndY); |
||
513 | gr.map(m_ctm); |
||
514 | GrStartX = gr.point(0).x() - crect.x(); |
||
515 | GrStartY = gr.point(0).y() - crect.y(); |
||
516 | GrEndX = gr.point(1).x() - crect.x(); |
||
517 | GrEndY = gr.point(1).y() - crect.y(); |
||
518 | double xCoor = m_doc->currentPage()->xOffset(); |
||
519 | double yCoor = m_doc->currentPage()->yOffset(); |
||
16746 | fschmid | 520 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
16729 | fschmid | 521 | QString output = QString("M %1 %2").arg(0.0).arg(0.0); |
522 | output += QString("L %1 %2").arg(crect.width()).arg(0.0); |
||
523 | output += QString("L %1 %2").arg(crect.width()).arg(crect.height()); |
||
524 | output += QString("L %1 %2").arg(0.0).arg(crect.height()); |
||
525 | output += QString("L %1 %2").arg(0.0).arg(0.0); |
||
526 | output += QString("Z"); |
||
527 | pathIsClosed = true; |
||
528 | Coords = output; |
||
529 | int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, CurrColorFill, CommonStrings::None, true); |
||
530 | PageItem* ite = m_doc->Items->at(z); |
||
531 | ite->ClipEdited = true; |
||
532 | ite->FrameType = 3; |
||
16746 | fschmid | 533 | ite->setFillShade(shade); |
16729 | fschmid | 534 | ite->setLineShade(100); |
535 | ite->setFillEvenOdd(false); |
||
536 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
537 | ite->setFillBlendmode(getBlendMode(state)); |
||
538 | ite->setLineEnd(PLineEnd); |
||
539 | ite->setLineJoin(PLineJoin); |
||
540 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
541 | ite->GrType = 6; |
||
542 | ite->fill_gradient = FillGradient; |
||
543 | ite->setGradientVector(GrStartX, GrStartY, GrEndX, GrEndY, 0, 0, 1, 0); |
||
544 | m_doc->AdjustItemSize(ite); |
||
545 | m_Elements->append(ite); |
||
546 | if (m_groupStack.count() != 0) |
||
547 | { |
||
548 | m_groupStack.top().Items.append(ite); |
||
16732 | fschmid | 549 | applyMask(ite); |
16729 | fschmid | 550 | } |
551 | return gTrue; |
||
552 | } |
||
553 | |||
554 | GBool SlaOutputDev::radialShadedFill(GfxState *state, GfxRadialShading *shading, double sMin, double sMax) |
||
555 | { |
||
556 | double GrStartX; |
||
557 | double GrStartY; |
||
558 | double GrEndX; |
||
559 | double GrEndY; |
||
16746 | fschmid | 560 | int shade = 100; |
16729 | fschmid | 561 | Function *func = shading->getFunc(0); |
562 | VGradient FillGradient = VGradient(VGradient::linear); |
||
563 | FillGradient.clearStops(); |
||
564 | GfxColorSpace *color_space = shading->getColorSpace(); |
||
565 | if (func->getType() == 3) |
||
566 | { |
||
567 | StitchingFunction *stitchingFunc = (StitchingFunction*)func; |
||
568 | double *bounds = stitchingFunc->getBounds(); |
||
569 | int num_funcs = stitchingFunc->getNumFuncs(); |
||
570 | // Add stops from all the stitched functions |
||
571 | for ( int i = 0 ; i < num_funcs ; i++ ) |
||
572 | { |
||
573 | GfxColor temp; |
||
574 | ((GfxRadialShading*)shading)->getColor(bounds[i], &temp); |
||
16746 | fschmid | 575 | QString stopColor = getColor(color_space, &temp, &shade); |
576 | FillGradient.addStop( ScColorEngine::getRGBColor(m_doc->PageColors[stopColor], m_doc), bounds[i], 0.5, 1.0, stopColor, shade ); |
||
16729 | fschmid | 577 | if (i == num_funcs - 1) |
578 | { |
||
579 | ((GfxRadialShading*)shading)->getColor(bounds[i+1], &temp); |
||
16746 | fschmid | 580 | QString stopColor = getColor(color_space, &temp, &shade); |
581 | FillGradient.addStop( ScColorEngine::getRGBColor(m_doc->PageColors[stopColor], m_doc), bounds[i+1], 0.5, 1.0, stopColor, shade ); |
||
16729 | fschmid | 582 | } |
583 | } |
||
584 | } |
||
585 | else if (func->getType() == 2) |
||
586 | { |
||
587 | GfxColor stop1; |
||
588 | ((GfxRadialShading*)shading)->getColor(0.0, &stop1); |
||
16746 | fschmid | 589 | QString stopColor1 = getColor(color_space, &stop1, &shade); |
590 | FillGradient.addStop( ScColorEngine::getRGBColor(m_doc->PageColors[stopColor1], m_doc), 0.0, 0.5, 1.0, stopColor1, shade ); |
||
16729 | fschmid | 591 | GfxColor stop2; |
592 | ((GfxRadialShading*)shading)->getColor(1.0, &stop2); |
||
16746 | fschmid | 593 | QString stopColor2 = getColor(color_space, &stop2, &shade); |
594 | FillGradient.addStop( ScColorEngine::getRGBColor(m_doc->PageColors[stopColor2], m_doc), 1.0, 0.5, 1.0, stopColor2, shade ); |
||
16729 | fschmid | 595 | } |
596 | double r0, x1, y1, r1; |
||
597 | ((GfxRadialShading*)shading)->getCoords(&GrStartX, &GrStartY, &r0, &x1, &y1, &r1); |
||
598 | double xmin, ymin, xmax, ymax; |
||
599 | // get the clip region bbox |
||
600 | state->getClipBBox(&xmin, &ymin, &xmax, &ymax); |
||
601 | QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); |
||
602 | crect = crect.normalized(); |
||
603 | double GrFocalX = x1; |
||
604 | double GrFocalY = y1; |
||
605 | GrEndX = GrFocalX + r1; |
||
606 | GrEndY = GrFocalY; |
||
607 | double *ctm; |
||
608 | ctm = state->getCTM(); |
||
609 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
610 | FPointArray gr; |
||
611 | gr.addPoint(GrStartX, GrStartY); |
||
612 | gr.addPoint(GrEndX, GrEndY); |
||
613 | gr.addPoint(GrFocalX, GrFocalY); |
||
614 | gr.map(m_ctm); |
||
615 | GrStartX = gr.point(0).x() - crect.x(); |
||
616 | GrStartY = gr.point(0).y() - crect.y(); |
||
617 | GrEndX = gr.point(1).x() - crect.x(); |
||
618 | GrEndY = gr.point(1).y() - crect.y(); |
||
619 | GrFocalX = gr.point(2).x() - crect.x(); |
||
620 | GrFocalY = gr.point(2).y() - crect.y(); |
||
621 | double xCoor = m_doc->currentPage()->xOffset(); |
||
622 | double yCoor = m_doc->currentPage()->yOffset(); |
||
16746 | fschmid | 623 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
16729 | fschmid | 624 | QString output = QString("M %1 %2").arg(0.0).arg(0.0); |
625 | output += QString("L %1 %2").arg(crect.width()).arg(0.0); |
||
626 | output += QString("L %1 %2").arg(crect.width()).arg(crect.height()); |
||
627 | output += QString("L %1 %2").arg(0.0).arg(crect.height()); |
||
628 | output += QString("L %1 %2").arg(0.0).arg(0.0); |
||
629 | output += QString("Z"); |
||
630 | pathIsClosed = true; |
||
631 | Coords = output; |
||
632 | int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, CurrColorFill, CommonStrings::None, true); |
||
633 | PageItem* ite = m_doc->Items->at(z); |
||
634 | ite->ClipEdited = true; |
||
635 | ite->FrameType = 3; |
||
16746 | fschmid | 636 | ite->setFillShade(shade); |
16729 | fschmid | 637 | ite->setLineShade(100); |
638 | ite->setFillEvenOdd(false); |
||
639 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
640 | ite->setFillBlendmode(getBlendMode(state)); |
||
641 | ite->setLineEnd(PLineEnd); |
||
642 | ite->setLineJoin(PLineJoin); |
||
643 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
644 | ite->GrType = 7; |
||
645 | ite->fill_gradient = FillGradient; |
||
646 | ite->setGradientVector(GrStartX, GrStartY, GrEndX, GrEndY, GrFocalX, GrFocalY, 1, 0); |
||
647 | m_doc->AdjustItemSize(ite); |
||
648 | m_Elements->append(ite); |
||
649 | if (m_groupStack.count() != 0) |
||
650 | { |
||
651 | m_groupStack.top().Items.append(ite); |
||
16732 | fschmid | 652 | applyMask(ite); |
16729 | fschmid | 653 | } |
654 | return gTrue; |
||
655 | } |
||
656 | |||
16745 | fschmid | 657 | GBool SlaOutputDev::gouraudTriangleShadedFill(GfxState *state, GfxGouraudTriangleShading *shading) |
658 | { |
||
659 | double xCoor = m_doc->currentPage()->xOffset(); |
||
660 | double yCoor = m_doc->currentPage()->yOffset(); |
||
16746 | fschmid | 661 | int shade = 100; |
662 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
16745 | fschmid | 663 | double xmin, ymin, xmax, ymax; |
664 | // get the clip region bbox |
||
665 | state->getClipBBox(&xmin, &ymin, &xmax, &ymax); |
||
666 | QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); |
||
667 | crect = crect.normalized(); |
||
668 | QString output = QString("M %1 %2").arg(0.0).arg(0.0); |
||
669 | output += QString("L %1 %2").arg(crect.width()).arg(0.0); |
||
670 | output += QString("L %1 %2").arg(crect.width()).arg(crect.height()); |
||
671 | output += QString("L %1 %2").arg(0.0).arg(crect.height()); |
||
672 | output += QString("L %1 %2").arg(0.0).arg(0.0); |
||
673 | output += QString("Z"); |
||
674 | pathIsClosed = true; |
||
675 | Coords = output; |
||
676 | double *ctm; |
||
677 | ctm = state->getCTM(); |
||
678 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
679 | int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, CurrColorFill, CommonStrings::None, true); |
||
680 | PageItem* ite = m_doc->Items->at(z); |
||
681 | ite->ClipEdited = true; |
||
682 | ite->FrameType = 3; |
||
683 | ite->setFillShade(100); |
||
684 | ite->setLineShade(100); |
||
685 | ite->setFillEvenOdd(false); |
||
686 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
687 | ite->setFillBlendmode(getBlendMode(state)); |
||
688 | ite->setLineEnd(PLineEnd); |
||
689 | ite->setLineJoin(PLineJoin); |
||
690 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
691 | m_doc->AdjustItemSize(ite); |
||
692 | m_Elements->append(ite); |
||
693 | if (m_groupStack.count() != 0) |
||
694 | { |
||
695 | m_groupStack.top().Items.append(ite); |
||
696 | applyMask(ite); |
||
697 | } |
||
698 | GfxColor color[3]; |
||
699 | double x0, y0, x1, y1, x2, y2; |
||
700 | for (int i = 0; i < shading->getNTriangles(); i++) |
||
701 | { |
||
702 | meshGradientPatch patchM; |
||
703 | shading->getTriangle(i, &x0, &y0, &color[0], &x1, &y1, &color[1], &x2, &y2, &color[2]); |
||
704 | patchM.BL.resetTo(FPoint(x0, y0)); |
||
705 | patchM.BL.shade = 100; |
||
706 | patchM.BL.transparency = 1.0; |
||
16746 | fschmid | 707 | patchM.BL.colorName = getColor(shading->getColorSpace(), &color[0], &shade); |
708 | patchM.BL.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.BL.colorName], m_doc, shade); |
||
16745 | fschmid | 709 | patchM.TL.resetTo(FPoint(x1, y1)); |
710 | patchM.TL.shade = 100; |
||
711 | patchM.TL.transparency = 1.0; |
||
16746 | fschmid | 712 | patchM.TL.colorName = getColor(shading->getColorSpace(), &color[1], &shade); |
713 | patchM.TL.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.TL.colorName], m_doc, shade); |
||
16745 | fschmid | 714 | patchM.TR.resetTo(FPoint(x2, y2)); |
715 | patchM.TR.shade = 100; |
||
716 | patchM.TR.transparency = 1.0; |
||
16746 | fschmid | 717 | patchM.TR.colorName = getColor(shading->getColorSpace(), &color[2], &shade); |
718 | patchM.TR.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.TR.colorName], m_doc, shade); |
||
16745 | fschmid | 719 | patchM.BR.resetTo(FPoint(x0, y0)); |
720 | patchM.BR.shade = 100; |
||
721 | patchM.BR.transparency = 1.0; |
||
16746 | fschmid | 722 | patchM.BR.colorName = getColor(shading->getColorSpace(), &color[0], &shade); |
723 | patchM.BR.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.BR.colorName], m_doc, shade); |
||
16745 | fschmid | 724 | patchM.TL.transform(m_ctm); |
725 | patchM.TL.moveRel(-crect.x(), -crect.y()); |
||
726 | patchM.TR.transform(m_ctm); |
||
727 | patchM.TR.moveRel(-crect.x(), -crect.y()); |
||
728 | patchM.BR.transform(m_ctm); |
||
729 | patchM.BR.moveRel(-crect.x(), -crect.y()); |
||
730 | patchM.BL.transform(m_ctm); |
||
731 | patchM.BL.moveRel(-crect.x(), -crect.y()); |
||
732 | ite->meshGradientPatches.append(patchM); |
||
733 | } |
||
734 | ite->GrType = 12; |
||
735 | return gTrue; |
||
736 | } |
||
737 | |||
16729 | fschmid | 738 | GBool SlaOutputDev::patchMeshShadedFill(GfxState *state, GfxPatchMeshShading *shading) |
739 | { |
||
740 | // qDebug() << "mesh shaded fill"; |
||
741 | double xCoor = m_doc->currentPage()->xOffset(); |
||
742 | double yCoor = m_doc->currentPage()->yOffset(); |
||
16746 | fschmid | 743 | int shade = 100; |
744 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
16729 | fschmid | 745 | double xmin, ymin, xmax, ymax; |
746 | // get the clip region bbox |
||
747 | state->getClipBBox(&xmin, &ymin, &xmax, &ymax); |
||
748 | QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); |
||
749 | crect = crect.normalized(); |
||
750 | QString output = QString("M %1 %2").arg(0.0).arg(0.0); |
||
751 | output += QString("L %1 %2").arg(crect.width()).arg(0.0); |
||
752 | output += QString("L %1 %2").arg(crect.width()).arg(crect.height()); |
||
753 | output += QString("L %1 %2").arg(0.0).arg(crect.height()); |
||
754 | output += QString("L %1 %2").arg(0.0).arg(0.0); |
||
755 | output += QString("Z"); |
||
756 | pathIsClosed = true; |
||
757 | Coords = output; |
||
758 | double *ctm; |
||
759 | ctm = state->getCTM(); |
||
760 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
761 | int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, CurrColorFill, CommonStrings::None, true); |
||
762 | PageItem* ite = m_doc->Items->at(z); |
||
763 | ite->ClipEdited = true; |
||
764 | ite->FrameType = 3; |
||
16746 | fschmid | 765 | ite->setFillShade(shade); |
16729 | fschmid | 766 | ite->setLineShade(100); |
767 | ite->setFillEvenOdd(false); |
||
768 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
769 | ite->setFillBlendmode(getBlendMode(state)); |
||
770 | ite->setLineEnd(PLineEnd); |
||
771 | ite->setLineJoin(PLineJoin); |
||
772 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
773 | m_doc->AdjustItemSize(ite); |
||
774 | m_Elements->append(ite); |
||
775 | if (m_groupStack.count() != 0) |
||
776 | { |
||
777 | m_groupStack.top().Items.append(ite); |
||
16732 | fschmid | 778 | applyMask(ite); |
16729 | fschmid | 779 | } |
780 | // qDebug() << "Mesh of" << shading->getNPatches() << "Patches"; |
||
781 | for (int i = 0; i < shading->getNPatches(); i++) |
||
782 | { |
||
783 | GfxPatch *patch = shading->getPatch(i); |
||
784 | GfxColor color; |
||
785 | meshGradientPatch patchM; |
||
786 | int u, v; |
||
787 | patchM.BL.resetTo(FPoint(patch->x[0][0], patch->y[0][0])); |
||
788 | patchM.BL.controlTop = FPoint(patch->x[0][1], patch->y[0][1]); |
||
789 | patchM.BL.controlRight = FPoint(patch->x[1][0], patch->y[1][0]); |
||
790 | u = 0; |
||
791 | v = 0; |
||
792 | if (shading->isParameterized()) |
||
793 | { |
||
794 | shading->getParameterizedColor (patch->color[u][v].c[0], &color); |
||
795 | } |
||
796 | else |
||
797 | { |
||
798 | for (int k = 0; k < shading->getColorSpace()->getNComps(); k++) |
||
799 | { |
||
800 | color.c[k] = GfxColorComp (patch->color[u][v].c[k]); |
||
801 | } |
||
802 | } |
||
16746 | fschmid | 803 | patchM.BL.colorName = getColor(shading->getColorSpace(), &color, &shade); |
16729 | fschmid | 804 | patchM.BL.shade = 100; |
805 | patchM.BL.transparency = 1.0; |
||
16746 | fschmid | 806 | patchM.BL.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.BL.colorName], m_doc, shade); |
16729 | fschmid | 807 | |
808 | u = 0; |
||
809 | v = 1; |
||
810 | patchM.TL.resetTo(FPoint(patch->x[0][3], patch->y[0][3])); |
||
811 | patchM.TL.controlRight = FPoint(patch->x[1][3], patch->y[1][3]); |
||
812 | patchM.TL.controlBottom = FPoint(patch->x[0][2], patch->y[0][2]); |
||
813 | if (shading->isParameterized()) |
||
814 | { |
||
815 | shading->getParameterizedColor (patch->color[u][v].c[0], &color); |
||
816 | } |
||
817 | else |
||
818 | { |
||
819 | for (int k = 0; k < shading->getColorSpace()->getNComps(); k++) |
||
820 | { |
||
821 | color.c[k] = GfxColorComp (patch->color[u][v].c[k]); |
||
822 | } |
||
823 | } |
||
16746 | fschmid | 824 | patchM.TL.colorName = getColor(shading->getColorSpace(), &color, &shade); |
16729 | fschmid | 825 | patchM.TL.shade = 100; |
826 | patchM.TL.transparency = 1.0; |
||
16746 | fschmid | 827 | patchM.TL.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.TL.colorName], m_doc, shade); |
16729 | fschmid | 828 | |
829 | u = 1; |
||
830 | v = 1; |
||
831 | patchM.TR.resetTo(FPoint(patch->x[3][3], patch->y[3][3])); |
||
832 | patchM.TR.controlBottom = FPoint(patch->x[3][2], patch->y[3][2]); |
||
833 | patchM.TR.controlLeft = FPoint(patch->x[2][3], patch->y[2][3]); |
||
834 | if (shading->isParameterized()) |
||
835 | { |
||
836 | shading->getParameterizedColor (patch->color[u][v].c[0], &color); |
||
837 | } |
||
838 | else |
||
839 | { |
||
840 | for (int k = 0; k < shading->getColorSpace()->getNComps(); k++) |
||
841 | { |
||
842 | color.c[k] = GfxColorComp (patch->color[u][v].c[k]); |
||
843 | } |
||
844 | } |
||
16746 | fschmid | 845 | patchM.TR.colorName = getColor(shading->getColorSpace(), &color, &shade); |
16729 | fschmid | 846 | patchM.TR.shade = 100; |
847 | patchM.TR.transparency = 1.0; |
||
16746 | fschmid | 848 | patchM.TR.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.TR.colorName], m_doc, shade); |
16729 | fschmid | 849 | |
850 | u = 1; |
||
851 | v = 0; |
||
852 | patchM.BR.resetTo(FPoint(patch->x[3][0], patch->y[3][0])); |
||
853 | patchM.BR.controlLeft = FPoint(patch->x[2][0], patch->y[2][0]); |
||
854 | patchM.BR.controlTop = FPoint(patch->x[3][1], patch->y[3][1]); |
||
855 | if (shading->isParameterized()) |
||
856 | { |
||
857 | shading->getParameterizedColor (patch->color[u][v].c[0], &color); |
||
858 | } |
||
859 | else |
||
860 | { |
||
861 | for (int k = 0; k < shading->getColorSpace()->getNComps(); k++) |
||
862 | { |
||
863 | color.c[k] = GfxColorComp (patch->color[u][v].c[k]); |
||
864 | } |
||
865 | } |
||
16746 | fschmid | 866 | patchM.BR.colorName = getColor(shading->getColorSpace(), &color, &shade); |
16729 | fschmid | 867 | patchM.BR.shade = 100; |
868 | patchM.BR.transparency = 1.0; |
||
16746 | fschmid | 869 | patchM.BR.color = ScColorEngine::getShadeColorProof(m_doc->PageColors[patchM.BR.colorName], m_doc, shade); |
16729 | fschmid | 870 | |
871 | patchM.TL.transform(m_ctm); |
||
872 | patchM.TL.moveRel(-crect.x(), -crect.y()); |
||
873 | patchM.TR.transform(m_ctm); |
||
874 | patchM.TR.moveRel(-crect.x(), -crect.y()); |
||
875 | patchM.BR.transform(m_ctm); |
||
876 | patchM.BR.moveRel(-crect.x(), -crect.y()); |
||
877 | patchM.BL.transform(m_ctm); |
||
878 | patchM.BL.moveRel(-crect.x(), -crect.y()); |
||
879 | ite->meshGradientPatches.append(patchM); |
||
880 | } |
||
881 | ite->GrType = 12; |
||
882 | return gTrue; |
||
883 | } |
||
884 | |||
885 | GBool SlaOutputDev::tilingPatternFill(GfxState *state, Catalog *cat, Object *str, double *pmat, int paintType, Dict *resDict, double *mat, double *bbox, int x0, int y0, int x1, int y1, double xStep, double yStep) |
||
886 | { |
||
887 | PDFRectangle box; |
||
888 | Gfx *gfx; |
||
889 | QString id; |
||
890 | PageItem *ite; |
||
891 | groupEntry gElements; |
||
892 | gElements.forSoftMask = gFalse; |
||
893 | gElements.alpha = gFalse; |
||
16732 | fschmid | 894 | gElements.inverted = false; |
16729 | fschmid | 895 | gElements.maskName = ""; |
896 | gElements.Items.clear(); |
||
897 | m_groupStack.push(gElements); |
||
898 | double width, height; |
||
899 | width = bbox[2] - bbox[0]; |
||
900 | height = bbox[3] - bbox[1]; |
||
901 | if (xStep != width || yStep != height) |
||
902 | return gFalse; |
||
903 | box.x1 = bbox[0]; |
||
904 | box.y1 = bbox[1]; |
||
905 | box.x2 = bbox[2]; |
||
906 | box.y2 = bbox[3]; |
||
907 | double *ctm; |
||
908 | ctm = state->getCTM(); |
||
909 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
910 | QTransform mm = QTransform(mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); |
||
911 | QTransform mmx = mm * m_ctm; |
||
912 | gfx = new Gfx(xref, this, resDict, catalog, &box, NULL); |
||
913 | gfx->display(str); |
||
914 | gElements = m_groupStack.pop(); |
||
915 | tmpSel->clear(); |
||
916 | double pwidth = 0; |
||
917 | double pheight = 0; |
||
918 | if (gElements.Items.count() > 0) |
||
919 | { |
||
920 | for (int dre = 0; dre < gElements.Items.count(); ++dre) |
||
921 | { |
||
922 | tmpSel->addItem(gElements.Items.at(dre), true); |
||
923 | m_Elements->removeAll(gElements.Items.at(dre)); |
||
924 | } |
||
925 | ite = m_doc->groupObjectsSelection(tmpSel); |
||
926 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
927 | ite->setFillBlendmode(getBlendMode(state)); |
||
928 | m_doc->m_Selection->addItem(ite, true); |
||
929 | m_doc->itemSelection_FlipV(); |
||
930 | m_doc->m_Selection->clear(); |
||
931 | ScPattern pat = ScPattern(); |
||
932 | pat.setDoc(m_doc); |
||
933 | m_doc->DoDrawing = true; |
||
934 | pat.pattern = ite->DrawObj_toImage(qMax(ite->width(), ite->height())); |
||
935 | pat.xoffset = 0; |
||
936 | pat.yoffset = 0; |
||
937 | m_doc->DoDrawing = false; |
||
938 | pat.width = ite->width(); |
||
939 | pat.height = ite->height(); |
||
940 | pwidth = ite->width(); |
||
941 | pheight = ite->height(); |
||
942 | pat.items.append(ite); |
||
943 | m_doc->Items->removeAll(ite); |
||
944 | id = QString("Pattern_from_PDF_%1").arg(m_doc->docPatterns.count() + 1); |
||
945 | m_doc->addPattern(id, pat); |
||
946 | tmpSel->clear(); |
||
947 | } |
||
948 | double xCoor = m_doc->currentPage()->xOffset(); |
||
949 | double yCoor = m_doc->currentPage()->yOffset(); |
||
16746 | fschmid | 950 | int shade = 100; |
951 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
16729 | fschmid | 952 | double xmin, ymin, xmax, ymax; |
953 | // get the clip region bbox |
||
954 | state->getClipBBox(&xmin, &ymin, &xmax, &ymax); |
||
955 | QRectF crect = QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); |
||
956 | crect = crect.normalized(); |
||
957 | QString output = QString("M %1 %2").arg(0.0).arg(0.0); |
||
958 | output += QString("L %1 %2").arg(crect.width()).arg(0.0); |
||
959 | output += QString("L %1 %2").arg(crect.width()).arg(crect.height()); |
||
960 | output += QString("L %1 %2").arg(0.0).arg(crect.height()); |
||
961 | output += QString("L %1 %2").arg(0.0).arg(0.0); |
||
962 | output += QString("Z"); |
||
963 | pathIsClosed = true; |
||
964 | Coords = output; |
||
965 | int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + crect.x(), yCoor + crect.y(), crect.width(), crect.height(), 0, CurrColorFill, CommonStrings::None, true); |
||
966 | ite = m_doc->Items->at(z); |
||
967 | ite->ClipEdited = true; |
||
968 | ite->FrameType = 3; |
||
16746 | fschmid | 969 | ite->setFillShade(shade); |
16729 | fschmid | 970 | ite->setLineShade(100); |
971 | ite->setFillEvenOdd(false); |
||
972 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
973 | ite->setFillBlendmode(getBlendMode(state)); |
||
974 | ite->setLineEnd(PLineEnd); |
||
975 | ite->setLineJoin(PLineJoin); |
||
976 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
977 | ite->GrType = 8; |
||
978 | ite->setPattern(id); |
||
979 | ite->setPatternTransform(fabs(pmat[0]) * 100, fabs(pmat[3]) * 100, mmx.dx() - ctm[4], mmx.dy() - ctm[5], 0, -1 * pmat[1], pmat[2]); |
||
980 | m_doc->AdjustItemSize(ite); |
||
981 | m_Elements->append(ite); |
||
982 | if (m_groupStack.count() != 0) |
||
983 | { |
||
984 | m_groupStack.top().Items.append(ite); |
||
16732 | fschmid | 985 | applyMask(ite); |
16729 | fschmid | 986 | } |
987 | delete gfx; |
||
988 | return gTrue; |
||
989 | } |
||
990 | |||
16751 | fschmid | 991 | void SlaOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool interpolate, GBool inlineImg) |
992 | { |
||
993 | // qDebug() << "Draw Image Mask"; |
||
994 | QImage * image = 0; |
||
995 | int invert_bit; |
||
996 | int row_stride; |
||
997 | int x, y, i, bit; |
||
998 | unsigned char *dest = 0; |
||
999 | unsigned char *buffer; |
||
1000 | Guchar *pix; |
||
1001 | ImageStream * imgStr = new ImageStream(str, width, 1, 1); |
||
1002 | imgStr->reset(); |
||
1003 | #ifdef WORDS_BIGENDIAN |
||
1004 | image = new QImage(width, height, QImage::Format_Mono); |
||
1005 | #else |
||
1006 | image = new QImage(width, height, QImage::Format_MonoLSB); |
||
1007 | #endif |
||
16764 | fschmid | 1008 | if (image == NULL || image->isNull()) |
1009 | { |
||
1010 | delete imgStr; |
||
1011 | delete image; |
||
1012 | return; |
||
1013 | } |
||
16751 | fschmid | 1014 | invert_bit = invert ? 1 : 0; |
1015 | buffer = image->bits(); |
||
1016 | row_stride = image->bytesPerLine(); |
||
1017 | for (y = 0; y < height; y++) |
||
1018 | { |
||
1019 | pix = imgStr->getLine(); |
||
1020 | dest = buffer + y * row_stride; |
||
1021 | i = 0; |
||
1022 | bit = 0; |
||
1023 | for (x = 0; x < width; x++) |
||
1024 | { |
||
1025 | if (bit == 0) |
||
1026 | dest[i] = 0; |
||
1027 | if (!(pix[x] ^ invert_bit)) |
||
1028 | { |
||
1029 | #ifdef WORDS_BIGENDIAN |
||
1030 | dest[i] |= (1 << (7 - bit)); |
||
1031 | #else |
||
1032 | dest[i] |= (1 << bit); |
||
1033 | #endif |
||
1034 | } |
||
1035 | bit++; |
||
1036 | if (bit > 7) |
||
1037 | { |
||
1038 | bit = 0; |
||
1039 | i++; |
||
1040 | } |
||
1041 | } |
||
1042 | } |
||
16764 | fschmid | 1043 | int shade = 100; |
1044 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
1045 | QColor backColor = ScColorEngine::getShadeColorProof(m_doc->PageColors[CurrColorFill], m_doc, shade); |
||
1046 | QImage res = QImage(width, height, QImage::Format_ARGB32); |
||
1047 | res.fill(backColor.rgb()); |
||
1048 | unsigned char cc, cm, cy, ck; |
||
1049 | for( int yi = 0; yi < res.height(); ++yi ) |
||
1050 | { |
||
1051 | QRgb *t = (QRgb*)(res.scanLine( yi )); |
||
1052 | for(int xi = 0; xi < res.width(); ++xi ) |
||
1053 | { |
||
1054 | cc = qRed(*t); |
||
1055 | cm = qGreen(*t); |
||
1056 | cy = qBlue(*t); |
||
1057 | ck = image->pixel(xi, yi); |
||
1058 | if (ck == 0) |
||
1059 | (*t) = qRgba(cc, cm, cy, 0); |
||
1060 | else |
||
1061 | (*t) = qRgba(cc, cm, cy, 255); |
||
1062 | t++; |
||
1063 | } |
||
1064 | } |
||
16751 | fschmid | 1065 | double *ctm; |
1066 | ctm = state->getCTM(); |
||
1067 | double xCoor = m_doc->currentPage()->xOffset(); |
||
1068 | double yCoor = m_doc->currentPage()->yOffset(); |
||
1069 | QRectF crect = QRectF(0, 0, width, height); |
||
1070 | m_ctm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, ctm[2] + ctm[4], ctm[3] + ctm[5]); |
||
1071 | QLineF cline = QLineF(0, 0, width, 0); |
||
1072 | QLineF tline = m_ctm.map(cline); |
||
1073 | QRectF trect = m_ctm.mapRect(crect); |
||
1074 | double sx = m_ctm.m11(); |
||
1075 | double sy = m_ctm.m22(); |
||
1076 | QTransform mm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, 0, 0); |
||
1077 | if ((mm.type() == QTransform::TxShear) || (mm.type() == QTransform::TxRotate)) |
||
1078 | { |
||
1079 | mm.reset(); |
||
1080 | mm.rotate(-tline.angle()); |
||
1081 | } |
||
1082 | else |
||
1083 | { |
||
1084 | mm.reset(); |
||
1085 | if (sx < 0) |
||
1086 | mm.scale(-1, 1); |
||
1087 | if (sy < 0) |
||
1088 | mm.scale(1, -1); |
||
1089 | } |
||
16764 | fschmid | 1090 | res = res.transformed(mm); |
1091 | if (res.isNull()) |
||
1092 | { |
||
1093 | delete imgStr; |
||
1094 | delete image; |
||
1095 | return; |
||
1096 | } |
||
16751 | fschmid | 1097 | int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, xCoor + trect.x(), yCoor + trect.y(), trect.width(), trect.height(), 0, CommonStrings::None, CommonStrings::None, true); |
1098 | PageItem* ite = m_doc->Items->at(z); |
||
1099 | ite->SetRectFrame(); |
||
1100 | m_doc->setRedrawBounding(ite); |
||
1101 | ite->Clip = FlattenPath(ite->PoLine, ite->Segments); |
||
1102 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
1103 | ite->setFillShade(100); |
||
1104 | ite->setLineShade(100); |
||
1105 | ite->setFillEvenOdd(false); |
||
1106 | ite->tempImageFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pdf_XXXXXX.png"); |
||
1107 | ite->tempImageFile->open(); |
||
1108 | QString fileName = getLongPathName(ite->tempImageFile->fileName()); |
||
1109 | ite->tempImageFile->close(); |
||
1110 | ite->isInlineImage = true; |
||
16764 | fschmid | 1111 | res.save(fileName, "PNG"); |
16751 | fschmid | 1112 | m_doc->LoadPict(fileName, z); |
1113 | ite->setImageScalingMode(false, true); |
||
1114 | m_doc->AdjustItemSize(ite); |
||
1115 | m_Elements->append(ite); |
||
1116 | if (m_groupStack.count() != 0) |
||
16764 | fschmid | 1117 | { |
16751 | fschmid | 1118 | m_groupStack.top().Items.append(ite); |
16764 | fschmid | 1119 | applyMask(ite); |
1120 | } |
||
16751 | fschmid | 1121 | imgStr->close(); |
1122 | delete imgStr; |
||
1123 | delete image; |
||
1124 | } |
||
1125 | |||
16729 | fschmid | 1126 | void SlaOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool interpolate, Stream *maskStr, int maskWidth, int maskHeight, |
1127 | GfxImageColorMap *maskColorMap, GBool maskInterpolate) |
||
1128 | { |
||
1129 | ImageStream * imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits()); |
||
1130 | imgStr->reset(); |
||
1131 | unsigned int *dest = 0; |
||
1132 | unsigned char * buffer = new unsigned char[width * height * 4]; |
||
1133 | QImage * image = 0; |
||
1134 | for (int y = 0; y < height; y++) |
||
1135 | { |
||
1136 | dest = (unsigned int *)(buffer + y * 4 * width); |
||
1137 | Guchar * pix = imgStr->getLine(); |
||
1138 | colorMap->getRGBLine(pix, dest, width); |
||
1139 | } |
||
1140 | image = new QImage(buffer, width, height, QImage::Format_RGB32); |
||
1141 | if (image == NULL || image->isNull()) |
||
1142 | { |
||
1143 | delete imgStr; |
||
1144 | delete[] buffer; |
||
1145 | delete image; |
||
1146 | return; |
||
1147 | } |
||
1148 | ImageStream *mskStr = new ImageStream(maskStr, maskWidth, maskColorMap->getNumPixelComps(), maskColorMap->getBits()); |
||
1149 | mskStr->reset(); |
||
1150 | Guchar *mdest = 0; |
||
1151 | unsigned char * mbuffer = new unsigned char[maskWidth * maskHeight]; |
||
1152 | for (int y = 0; y < maskHeight; y++) |
||
1153 | { |
||
1154 | mdest = (Guchar *)(mbuffer + y * maskWidth); |
||
1155 | Guchar * pix = mskStr->getLine(); |
||
1156 | maskColorMap->getGrayLine(pix, mdest, maskWidth); |
||
1157 | } |
||
1158 | if ((maskWidth != width) || (maskHeight != height)) |
||
1159 | { |
||
1160 | delete imgStr; |
||
1161 | delete[] buffer; |
||
1162 | delete image; |
||
1163 | delete mskStr; |
||
1164 | delete[] mbuffer; |
||
1165 | return; |
||
1166 | } |
||
1167 | QImage res = image->convertToFormat(QImage::Format_ARGB32); |
||
1168 | unsigned char cc, cm, cy, ck; |
||
1169 | int s = 0; |
||
1170 | for( int yi=0; yi < res.height(); ++yi ) |
||
1171 | { |
||
1172 | QRgb *t = (QRgb*)(res.scanLine( yi )); |
||
1173 | for(int xi=0; xi < res.width(); ++xi ) |
||
1174 | { |
||
1175 | cc = qRed(*t); |
||
1176 | cm = qGreen(*t); |
||
1177 | cy = qBlue(*t); |
||
1178 | ck = mbuffer[s]; |
||
1179 | (*t) = qRgba(cc, cm, cy, ck); |
||
1180 | s++; |
||
1181 | t++; |
||
1182 | } |
||
1183 | } |
||
16751 | fschmid | 1184 | double *ctm; |
1185 | ctm = state->getCTM(); |
||
16729 | fschmid | 1186 | double xCoor = m_doc->currentPage()->xOffset(); |
1187 | double yCoor = m_doc->currentPage()->yOffset(); |
||
16751 | fschmid | 1188 | QRectF crect = QRectF(0, 0, width, height); |
1189 | m_ctm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, ctm[2] + ctm[4], ctm[3] + ctm[5]); |
||
1190 | QLineF cline = QLineF(0, 0, width, 0); |
||
1191 | QLineF tline = m_ctm.map(cline); |
||
1192 | QRectF trect = m_ctm.mapRect(crect); |
||
1193 | double sx = m_ctm.m11(); |
||
1194 | double sy = m_ctm.m22(); |
||
1195 | QTransform mm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, 0, 0); |
||
1196 | if ((mm.type() == QTransform::TxShear) || (mm.type() == QTransform::TxRotate)) |
||
1197 | { |
||
1198 | mm.reset(); |
||
1199 | mm.rotate(-tline.angle()); |
||
1200 | } |
||
16729 | fschmid | 1201 | else |
16751 | fschmid | 1202 | { |
1203 | mm.reset(); |
||
1204 | if (sx < 0) |
||
1205 | mm.scale(-1, 1); |
||
1206 | if (sy < 0) |
||
1207 | mm.scale(1, -1); |
||
1208 | } |
||
16764 | fschmid | 1209 | res = res.transformed(mm); |
16751 | fschmid | 1210 | int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, xCoor + trect.x(), yCoor + trect.y(), trect.width(), trect.height(), 0, CommonStrings::None, CommonStrings::None, true); |
16729 | fschmid | 1211 | PageItem* ite = m_doc->Items->at(z); |
1212 | ite->SetRectFrame(); |
||
1213 | m_doc->setRedrawBounding(ite); |
||
1214 | ite->Clip = FlattenPath(ite->PoLine, ite->Segments); |
||
1215 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
1216 | ite->setFillShade(100); |
||
1217 | ite->setLineShade(100); |
||
1218 | ite->setFillEvenOdd(false); |
||
1219 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
1220 | ite->setFillBlendmode(getBlendMode(state)); |
||
1221 | ite->tempImageFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pdf_XXXXXX.png"); |
||
1222 | ite->tempImageFile->open(); |
||
1223 | QString fileName = getLongPathName(ite->tempImageFile->fileName()); |
||
1224 | ite->tempImageFile->close(); |
||
1225 | ite->isInlineImage = true; |
||
16764 | fschmid | 1226 | res.save(fileName, "PNG"); |
16729 | fschmid | 1227 | m_doc->LoadPict(fileName, z); |
1228 | ite->setImageScalingMode(false, true); |
||
1229 | m_doc->AdjustItemSize(ite); |
||
1230 | m_Elements->append(ite); |
||
1231 | if (m_groupStack.count() != 0) |
||
1232 | { |
||
1233 | m_groupStack.top().Items.append(ite); |
||
16732 | fschmid | 1234 | applyMask(ite); |
16729 | fschmid | 1235 | } |
1236 | delete imgStr; |
||
1237 | delete[] buffer; |
||
1238 | delete image; |
||
1239 | delete mskStr; |
||
1240 | delete[] mbuffer; |
||
1241 | } |
||
1242 | |||
1243 | void SlaOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool interpolate, int *maskColors, GBool inlineImg) |
||
1244 | { |
||
1245 | ImageStream * imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), colorMap->getBits()); |
||
1246 | imgStr->reset(); |
||
1247 | unsigned int *dest = 0; |
||
1248 | unsigned char * buffer = new unsigned char[width * height * 4]; |
||
1249 | QImage * image = 0; |
||
1250 | if (maskColors) |
||
1251 | { |
||
1252 | for (int y = 0; y < height; y++) |
||
1253 | { |
||
1254 | dest = (unsigned int *)(buffer + y * 4 * width); |
||
1255 | Guchar * pix = imgStr->getLine(); |
||
1256 | colorMap->getRGBLine(pix, dest, width); |
||
1257 | for (int x = 0; x < width; x++) |
||
1258 | { |
||
1259 | for (int i = 0; i < colorMap->getNumPixelComps(); ++i) |
||
1260 | { |
||
1261 | if (pix[i] < maskColors[2*i] * 255 || pix[i] > maskColors[2*i+1] * 255) |
||
1262 | { |
||
1263 | *dest = *dest | 0xff000000; |
||
1264 | break; |
||
1265 | } |
||
1266 | } |
||
1267 | pix += colorMap->getNumPixelComps(); |
||
1268 | dest++; |
||
1269 | } |
||
1270 | } |
||
1271 | image = new QImage(buffer, width, height, QImage::Format_ARGB32); |
||
1272 | } |
||
1273 | else |
||
1274 | { |
||
1275 | for (int y = 0; y < height; y++) |
||
1276 | { |
||
1277 | dest = (unsigned int *)(buffer + y * 4 * width); |
||
1278 | Guchar * pix = imgStr->getLine(); |
||
1279 | colorMap->getRGBLine(pix, dest, width); |
||
1280 | } |
||
1281 | image = new QImage(buffer, width, height, QImage::Format_RGB32); |
||
1282 | } |
||
1283 | if (image == NULL || image->isNull()) |
||
1284 | { |
||
1285 | delete imgStr; |
||
1286 | delete[] buffer; |
||
1287 | delete image; |
||
1288 | return; |
||
1289 | } |
||
16751 | fschmid | 1290 | double *ctm; |
1291 | ctm = state->getCTM(); |
||
16729 | fschmid | 1292 | double xCoor = m_doc->currentPage()->xOffset(); |
1293 | double yCoor = m_doc->currentPage()->yOffset(); |
||
16751 | fschmid | 1294 | QRectF crect = QRectF(0, 0, width, height); |
1295 | m_ctm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, ctm[2] + ctm[4], ctm[3] + ctm[5]); |
||
1296 | QLineF cline = QLineF(0, 0, width, 0); |
||
1297 | QLineF tline = m_ctm.map(cline); |
||
1298 | QRectF trect = m_ctm.mapRect(crect); |
||
1299 | double sx = m_ctm.m11(); |
||
1300 | double sy = m_ctm.m22(); |
||
1301 | QTransform mm = QTransform(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / height, 0, 0); |
||
1302 | if ((mm.type() == QTransform::TxShear) || (mm.type() == QTransform::TxRotate)) |
||
1303 | { |
||
1304 | mm.reset(); |
||
1305 | mm.rotate(-tline.angle()); |
||
1306 | } |
||
16729 | fschmid | 1307 | else |
16751 | fschmid | 1308 | { |
1309 | mm.reset(); |
||
1310 | if (sx < 0) |
||
1311 | mm.scale(-1, 1); |
||
1312 | if (sy < 0) |
||
1313 | mm.scale(1, -1); |
||
1314 | } |
||
1315 | QImage img = image->transformed(mm); |
||
1316 | int z = m_doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, xCoor + trect.x(), yCoor + trect.y(), trect.width(), trect.height(), 0, CommonStrings::None, CommonStrings::None, true); |
||
16729 | fschmid | 1317 | PageItem* ite = m_doc->Items->at(z); |
1318 | ite->SetRectFrame(); |
||
1319 | m_doc->setRedrawBounding(ite); |
||
1320 | ite->Clip = FlattenPath(ite->PoLine, ite->Segments); |
||
1321 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
1322 | ite->setFillShade(100); |
||
1323 | ite->setLineShade(100); |
||
1324 | ite->setFillEvenOdd(false); |
||
1325 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
1326 | ite->setFillBlendmode(getBlendMode(state)); |
||
1327 | ite->tempImageFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_pdf_XXXXXX.png"); |
||
1328 | ite->tempImageFile->open(); |
||
1329 | QString fileName = getLongPathName(ite->tempImageFile->fileName()); |
||
1330 | ite->tempImageFile->close(); |
||
1331 | ite->isInlineImage = true; |
||
16751 | fschmid | 1332 | img.save(fileName, "PNG"); |
16729 | fschmid | 1333 | m_doc->LoadPict(fileName, z); |
1334 | ite->setImageScalingMode(false, true); |
||
1335 | m_doc->AdjustItemSize(ite); |
||
1336 | m_Elements->append(ite); |
||
1337 | if (m_groupStack.count() != 0) |
||
1338 | { |
||
1339 | m_groupStack.top().Items.append(ite); |
||
16732 | fschmid | 1340 | applyMask(ite); |
16729 | fschmid | 1341 | } |
1342 | delete imgStr; |
||
1343 | delete[] buffer; |
||
1344 | delete image; |
||
1345 | } |
||
1346 | |||
1347 | void SlaOutputDev::beginMarkedContent(char *name, Dict *properties) |
||
1348 | { |
||
1349 | // qDebug() << "Begin Marked Content with Name " << QString(name); |
||
1350 | if (importerFlags & LoadSavePlugin::lfCreateDoc) |
||
1351 | { |
||
1352 | if (QString(name) == "Layer") // Handle Adobe Illustrator Layer command |
||
1353 | { |
||
1354 | layerNum++; |
||
1355 | if (!firstLayer) |
||
1356 | currentLayer = m_doc->addLayer(QString("Layer_%1").arg(layerNum), true); |
||
1357 | firstLayer = false; |
||
1358 | Object obj; |
||
1359 | if (properties->lookup((char*)"Title", &obj)) |
||
1360 | { |
||
1361 | if (obj.isString()) |
||
1362 | { |
||
1363 | QString lName = QString(obj.getString()->getCString()); |
||
1364 | m_doc->changeLayerName(currentLayer, lName); |
||
1365 | } |
||
1366 | obj.free(); |
||
1367 | } |
||
1368 | if (properties->lookup((char*)"Visible", &obj)) |
||
1369 | { |
||
1370 | if (obj.isBool()) |
||
1371 | m_doc->setLayerVisible(currentLayer, obj.getBool()); |
||
1372 | obj.free(); |
||
1373 | } |
||
1374 | if (properties->lookup((char*)"Editable", &obj)) |
||
1375 | { |
||
1376 | if (obj.isBool()) |
||
1377 | m_doc->setLayerLocked(currentLayer, !obj.getBool()); |
||
1378 | obj.free(); |
||
1379 | } |
||
1380 | if (properties->lookup((char*)"Printed", &obj)) |
||
1381 | { |
||
1382 | if (obj.isBool()) |
||
1383 | m_doc->setLayerPrintable(currentLayer, obj.getBool()); |
||
1384 | obj.free(); |
||
1385 | } |
||
1386 | if (properties->lookup((char*)"Color", &obj)) |
||
1387 | { |
||
1388 | if (obj.isArray()) |
||
1389 | { |
||
1390 | Object obj1; |
||
1391 | obj.arrayGet(0, &obj1); |
||
1392 | int r = obj1.getNum() / 256; |
||
1393 | obj1.free(); |
||
1394 | obj.arrayGet(1, &obj1); |
||
1395 | int g = obj1.getNum() / 256; |
||
1396 | obj1.free(); |
||
1397 | obj.arrayGet(2, &obj1); |
||
1398 | int b = obj1.getNum() / 256; |
||
1399 | obj1.free(); |
||
1400 | m_doc->setLayerMarker(currentLayer, QColor(r, g, b)); |
||
1401 | } |
||
1402 | obj.free(); |
||
1403 | } |
||
1404 | } |
||
1405 | } |
||
1406 | } |
||
1407 | |||
1408 | void SlaOutputDev::endMarkedContent(GfxState *state) |
||
1409 | { |
||
1410 | // qDebug() << "End Marked Content"; |
||
1411 | } |
||
1412 | |||
1413 | void SlaOutputDev::updateFont(GfxState *state) |
||
1414 | { |
||
1415 | GfxFont *gfxFont; |
||
1416 | GfxFontType fontType; |
||
1417 | SplashOutFontFileID *id; |
||
1418 | SplashFontFile *fontFile; |
||
1419 | SplashFontSrc *fontsrc = NULL; |
||
1420 | FoFiTrueType *ff; |
||
1421 | Ref embRef; |
||
1422 | Object refObj, strObj; |
||
1423 | GooString *fileName; |
||
1424 | char *tmpBuf; |
||
1425 | int tmpBufLen; |
||
1426 | Gushort *codeToGID; |
||
1427 | DisplayFontParam *dfp; |
||
1428 | double *textMat; |
||
1429 | double m11, m12, m21, m22, fontSize; |
||
1430 | SplashCoord mat[4]; |
||
1431 | int n; |
||
1432 | int faceIndex = 0; |
||
1433 | SplashCoord matrix[6]; |
||
1434 | |||
1435 | m_font = NULL; |
||
1436 | fileName = NULL; |
||
1437 | tmpBuf = NULL; |
||
1438 | |||
1439 | if (!(gfxFont = state->getFont())) |
||
1440 | goto err1; |
||
1441 | fontType = gfxFont->getType(); |
||
1442 | if (fontType == fontType3) |
||
1443 | goto err1; |
||
1444 | |||
1445 | // check the font file cache |
||
1446 | id = new SplashOutFontFileID(gfxFont->getID()); |
||
1447 | if ((fontFile = m_fontEngine->getFontFile(id))) |
||
1448 | { |
||
1449 | delete id; |
||
1450 | } |
||
1451 | else |
||
1452 | { |
||
1453 | // if there is an embedded font, write it to disk |
||
1454 | if (gfxFont->getEmbeddedFontID(&embRef)) |
||
1455 | { |
||
1456 | tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen); |
||
1457 | if (!tmpBuf) |
||
1458 | goto err2; |
||
1459 | // if there is an external font file, use it |
||
1460 | } |
||
1461 | else if (!(fileName = gfxFont->getExtFontFile())) |
||
1462 | { |
||
1463 | // look for a display font mapping or a substitute font |
||
1464 | dfp = NULL; |
||
1465 | if (gfxFont->getName()) |
||
1466 | { |
||
1467 | dfp = globalParams->getDisplayFont(gfxFont); |
||
1468 | } |
||
1469 | if (!dfp) |
||
1470 | { |
||
1471 | // error(-1, "Couldn't find a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); |
||
1472 | goto err2; |
||
1473 | } |
||
1474 | switch (dfp->kind) |
||
1475 | { |
||
1476 | case displayFontT1: |
||
1477 | fileName = dfp->t1.fileName; |
||
1478 | fontType = gfxFont->isCIDFont() ? fontCIDType0 : fontType1; |
||
1479 | break; |
||
1480 | case displayFontTT: |
||
1481 | fileName = dfp->tt.fileName; |
||
1482 | fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType; |
||
1483 | faceIndex = dfp->tt.faceIndex; |
||
1484 | break; |
||
1485 | } |
||
1486 | } |
||
1487 | fontsrc = new SplashFontSrc; |
||
1488 | if (fileName) |
||
1489 | fontsrc->setFile(fileName, gFalse); |
||
1490 | else |
||
1491 | fontsrc->setBuf(tmpBuf, tmpBufLen, gTrue); |
||
1492 | // load the font file |
||
1493 | switch (fontType) |
||
1494 | { |
||
1495 | case fontType1: |
||
1496 | if (!(fontFile = m_fontEngine->loadType1Font( id, fontsrc, ((Gfx8BitFont *)gfxFont)->getEncoding()))) |
||
1497 | { |
||
1498 | // error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); |
||
1499 | goto err2; |
||
1500 | } |
||
1501 | break; |
||
1502 | case fontType1C: |
||
1503 | if (!(fontFile = m_fontEngine->loadType1CFont( id, fontsrc, ((Gfx8BitFont *)gfxFont)->getEncoding()))) |
||
1504 | { |
||
1505 | // error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); |
||
1506 | goto err2; |
||
1507 | } |
||
1508 | break; |
||
1509 | case fontType1COT: |
||
1510 | if (!(fontFile = m_fontEngine->loadOpenTypeT1CFont( id, fontsrc, ((Gfx8BitFont *)gfxFont)->getEncoding()))) |
||
1511 | { |
||
1512 | // error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); |
||
1513 | goto err2; |
||
1514 | } |
||
1515 | break; |
||
1516 | case fontTrueType: |
||
1517 | case fontTrueTypeOT: |
||
1518 | if (fileName) |
||
1519 | ff = FoFiTrueType::load(fileName->getCString()); |
||
1520 | else |
||
1521 | ff = FoFiTrueType::make(tmpBuf, tmpBufLen); |
||
1522 | if (ff) |
||
1523 | { |
||
1524 | codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff); |
||
1525 | n = 256; |
||
1526 | delete ff; |
||
1527 | } |
||
1528 | else |
||
1529 | { |
||
1530 | codeToGID = NULL; |
||
1531 | n = 0; |
||
1532 | } |
||
1533 | if (!(fontFile = m_fontEngine->loadTrueTypeFont( id, fontsrc, codeToGID, n))) |
||
1534 | { |
||
1535 | // error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); |
||
1536 | goto err2; |
||
1537 | } |
||
1538 | break; |
||
1539 | case fontCIDType0: |
||
1540 | case fontCIDType0C: |
||
1541 | if (!(fontFile = m_fontEngine->loadCIDFont( id, fontsrc))) |
||
1542 | { |
||
1543 | // error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); |
||
1544 | goto err2; |
||
1545 | } |
||
1546 | break; |
||
1547 | case fontCIDType0COT: |
||
1548 | if (!(fontFile = m_fontEngine->loadOpenTypeCFFFont( id, fontsrc))) |
||
1549 | { |
||
1550 | // error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); |
||
1551 | goto err2; |
||
1552 | } |
||
1553 | break; |
||
1554 | case fontCIDType2: |
||
1555 | case fontCIDType2OT: |
||
1556 | codeToGID = NULL; |
||
1557 | n = 0; |
||
1558 | if (((GfxCIDFont *)gfxFont)->getCIDToGID()) |
||
1559 | { |
||
1560 | n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); |
||
1561 | if (n) |
||
1562 | { |
||
1563 | codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort)); |
||
1564 | memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), n * sizeof(Gushort)); |
||
1565 | } |
||
1566 | } |
||
1567 | else |
||
1568 | { |
||
1569 | if (fileName) |
||
1570 | ff = FoFiTrueType::load(fileName->getCString()); |
||
1571 | else |
||
1572 | ff = FoFiTrueType::make(tmpBuf, tmpBufLen); |
||
1573 | if (!ff) |
||
1574 | goto err2; |
||
1575 | codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n); |
||
1576 | delete ff; |
||
1577 | } |
||
1578 | if (!(fontFile = m_fontEngine->loadTrueTypeFont( id, fontsrc, codeToGID, n, faceIndex))) |
||
1579 | { |
||
1580 | // error(-1, "Couldn't create a font for '%s'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); |
||
1581 | goto err2; |
||
1582 | } |
||
1583 | break; |
||
1584 | default: |
||
1585 | // this shouldn't happen |
||
1586 | goto err2; |
||
1587 | } |
||
1588 | } |
||
1589 | // get the font matrix |
||
1590 | textMat = state->getTextMat(); |
||
1591 | fontSize = state->getFontSize(); |
||
1592 | m11 = textMat[0] * fontSize * state->getHorizScaling(); |
||
1593 | m12 = textMat[1] * fontSize * state->getHorizScaling(); |
||
1594 | m21 = textMat[2] * fontSize; |
||
1595 | m22 = textMat[3] * fontSize; |
||
1596 | matrix[0] = 1; |
||
1597 | matrix[1] = 0; |
||
1598 | matrix[2] = 0; |
||
1599 | matrix[3] = 1; |
||
1600 | matrix[4] = 0; |
||
1601 | matrix[5] = 0; |
||
1602 | // create the scaled font |
||
1603 | mat[0] = m11; |
||
1604 | mat[1] = -m12; |
||
1605 | mat[2] = m21; |
||
1606 | mat[3] = -m22; |
||
1607 | m_font = m_fontEngine->getFont(fontFile, mat, matrix); |
||
1608 | if (fontsrc && !fontsrc->isFile) |
||
1609 | fontsrc->unref(); |
||
1610 | return; |
||
1611 | |||
1612 | err2: |
||
1613 | delete id; |
||
1614 | err1: |
||
1615 | if (fontsrc && !fontsrc->isFile) |
||
1616 | fontsrc->unref(); |
||
1617 | return; |
||
1618 | } |
||
1619 | |||
1620 | void SlaOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, Unicode *u, int uLen) |
||
1621 | { |
||
1622 | double x1, y1, x2, y2; |
||
1623 | int render; |
||
1624 | updateFont(state); |
||
1625 | if (!m_font) |
||
1626 | return; |
||
1627 | // check for invisible text -- this is used by Acrobat Capture |
||
1628 | render = state->getRender(); |
||
1629 | if (render == 3) |
||
1630 | return; |
||
1631 | if (!(render & 1)) |
||
1632 | { |
||
1633 | SplashPath * fontPath; |
||
1634 | fontPath = m_font->getGlyphPath(code); |
||
1635 | if (fontPath) |
||
1636 | { |
||
1637 | QPainterPath qPath; |
||
1638 | qPath.setFillRule(Qt::WindingFill); |
||
1639 | for (int i = 0; i < fontPath->getLength(); ++i) |
||
1640 | { |
||
1641 | Guchar f; |
||
1642 | fontPath->getPoint(i, &x1, &y1, &f); |
||
1643 | if (f & splashPathFirst) |
||
1644 | qPath.moveTo(x1,y1); |
||
1645 | else if (f & splashPathCurve) |
||
1646 | { |
||
1647 | double x3, y3; |
||
1648 | ++i; |
||
1649 | fontPath->getPoint(i, &x2, &y2, &f); |
||
1650 | ++i; |
||
1651 | fontPath->getPoint(i, &x3, &y3, &f); |
||
1652 | qPath.cubicTo(x1,y1,x2,y2,x3,y3); |
||
1653 | } |
||
1654 | else |
||
1655 | qPath.lineTo(x1,y1); |
||
1656 | if (f & splashPathLast) |
||
1657 | qPath.closeSubpath(); |
||
1658 | } |
||
1659 | double *ctm; |
||
1660 | ctm = state->getCTM(); |
||
1661 | m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
1662 | double xCoor = m_doc->currentPage()->xOffset(); |
||
1663 | double yCoor = m_doc->currentPage()->yOffset(); |
||
16746 | fschmid | 1664 | int shade = 100; |
1665 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
16729 | fschmid | 1666 | FPointArray textPath; |
1667 | textPath.fromQPainterPath(qPath); |
||
1668 | FPoint wh = textPath.WidthHeight(); |
||
1669 | if ((textPath.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0))) |
||
1670 | { |
||
1671 | int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CurrColorFill, CommonStrings::None, true); |
||
1672 | PageItem* ite = m_doc->Items->at(z); |
||
1673 | FPoint tp2(getMinClipF(&textPath)); |
||
1674 | QTransform mm; |
||
1675 | mm.scale(1, -1); |
||
1676 | mm.translate(x, -y); |
||
1677 | textPath.map(mm); |
||
1678 | textPath.map(m_ctm); |
||
1679 | ite->PoLine = textPath.copy(); |
||
1680 | ite->ClipEdited = true; |
||
1681 | ite->FrameType = 3; |
||
16746 | fschmid | 1682 | ite->setFillShade(shade); |
16729 | fschmid | 1683 | ite->setFillEvenOdd(false); |
1684 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
1685 | ite->setFillBlendmode(getBlendMode(state)); |
||
1686 | ite->setLineEnd(PLineEnd); |
||
1687 | ite->setLineJoin(PLineJoin); |
||
1688 | ite->setTextFlowMode(PageItem::TextFlowDisabled); |
||
1689 | m_doc->AdjustItemSize(ite); |
||
1690 | if ((render & 3) == 1 || (render & 3) == 2) |
||
1691 | { |
||
16746 | fschmid | 1692 | CurrColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &shade); |
16729 | fschmid | 1693 | ite->setLineColor(CurrColorStroke); |
1694 | ite->setLineWidth(state->getTransformedLineWidth()); |
||
1695 | ite->setLineTransparency(1.0 - state->getStrokeOpacity()); |
||
1696 | ite->setLineBlendmode(getBlendMode(state)); |
||
16746 | fschmid | 1697 | ite->setLineShade(shade); |
16729 | fschmid | 1698 | } |
1699 | m_Elements->append(ite); |
||
1700 | if (m_groupStack.count() != 0) |
||
1701 | { |
||
1702 | m_groupStack.top().Items.append(ite); |
||
16732 | fschmid | 1703 | applyMask(ite); |
16729 | fschmid | 1704 | } |
1705 | delete fontPath; |
||
1706 | } |
||
1707 | } |
||
1708 | } |
||
1709 | } |
||
1710 | |||
16766 | fschmid | 1711 | GBool SlaOutputDev::beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen) |
1712 | { |
||
1713 | double *ctm; |
||
1714 | ctm = state->getCTM(); |
||
1715 | QTransform orig_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); |
||
1716 | GfxFont *gfxFont; |
||
1717 | GfxFontType fontType; |
||
1718 | if (!(gfxFont = state->getFont())) |
||
1719 | return gTrue; |
||
1720 | fontType = gfxFont->getType(); |
||
1721 | if (fontType != fontType3) |
||
1722 | return gTrue; |
||
1723 | Ref* fref = gfxFont->getID(); |
||
1724 | QString fRefID = QString("Font_%1_%2").arg(fref->num).arg(code); |
||
1725 | if (m_Font_Pattern_Map.contains(fRefID)) |
||
1726 | { |
||
1727 | QLineF cline = QLineF(0, 0, 1, 0); |
||
1728 | QLineF tline = orig_ctm.map(cline); |
||
1729 | double xCoor = m_doc->currentPage()->xOffset(); |
||
1730 | double yCoor = m_doc->currentPage()->yOffset(); |
||
1731 | ScPattern pat = m_doc->docPatterns[m_Font_Pattern_Map[fRefID]]; |
||
1732 | QTransform mm; |
||
1733 | mm.translate(0, -pat.height * tline.length()); |
||
1734 | mm = orig_ctm * mm; |
||
1735 | int shade = 100; |
||
1736 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
1737 | int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + mm.dx(), yCoor + mm.dy(), pat.width * tline.length(), pat.height * tline.length(), 0, CurrColorFill, CommonStrings::None, true); |
||
1738 | PageItem *b = m_doc->Items->at(z); |
||
1739 | b->setWidth(pat.width * tline.length()); |
||
1740 | b->setHeight(pat.height * tline.length()); |
||
1741 | b->OldB2 = b->width(); |
||
1742 | b->OldH2 = b->height(); |
||
1743 | m_doc->RotMode(3); |
||
1744 | m_doc->RotateItem(-tline.angle(), b); |
||
1745 | m_doc->RotMode(0); |
||
1746 | b->setFillShade(shade); |
||
1747 | b->setFillEvenOdd(false); |
||
1748 | b->setFillTransparency(1.0 - state->getFillOpacity()); |
||
1749 | b->setFillBlendmode(getBlendMode(state)); |
||
1750 | b->setLineEnd(PLineEnd); |
||
1751 | b->setLineJoin(PLineJoin); |
||
1752 | b->setTextFlowMode(PageItem::TextFlowDisabled); |
||
1753 | b->setPatternMask(m_Font_Pattern_Map[fRefID]); |
||
1754 | b->setMaskTransform(b->width() / pat.width * 100, b->height() / pat.height * 100, 0, 0, 0, 0, 0); |
||
1755 | b->setMaskType(3); |
||
1756 | m_Elements->append(b); |
||
1757 | if (m_groupStack.count() != 0) |
||
1758 | { |
||
1759 | m_groupStack.top().Items.append(b); |
||
1760 | } |
||
1761 | return gTrue; |
||
1762 | } |
||
1763 | else |
||
1764 | { |
||
1765 | F3Entry f3e; |
||
1766 | f3e.ctm = orig_ctm; |
||
1767 | f3e.glyphRef = fRefID; |
||
1768 | m_F3Stack.push(f3e); |
||
1769 | ctm = state->getTextMat(); |
||
1770 | state->setCTM(ctm[0], ctm[1], ctm[2], ctm[3], 0, 0); |
||
1771 | pushGroup(); |
||
1772 | return gFalse; |
||
1773 | } |
||
1774 | } |
||
1775 | |||
1776 | void SlaOutputDev::endType3Char(GfxState *state) |
||
1777 | { |
||
1778 | double *ctm; |
||
1779 | ctm = state->getCTM(); |
||
1780 | groupEntry gElements = m_groupStack.pop(); |
||
1781 | tmpSel->clear(); |
||
1782 | if (gElements.Items.count() > 0) |
||
1783 | { |
||
1784 | for (int dre = 0; dre < gElements.Items.count(); ++dre) |
||
1785 | { |
||
1786 | tmpSel->addItem(gElements.Items.at(dre), true); |
||
1787 | m_Elements->removeAll(gElements.Items.at(dre)); |
||
1788 | } |
||
1789 | PageItem *ite = m_doc->groupObjectsSelection(tmpSel); |
||
1790 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
1791 | ite->setFillBlendmode(getBlendMode(state)); |
||
1792 | m_doc->m_Selection->addItem(ite, true); |
||
1793 | m_doc->itemSelection_FlipV(); |
||
1794 | m_doc->m_Selection->clear(); |
||
1795 | ScPattern pat = ScPattern(); |
||
1796 | pat.setDoc(m_doc); |
||
1797 | m_doc->DoDrawing = true; |
||
1798 | pat.pattern = ite->DrawObj_toImage(qMax(ite->width(), ite->height())); |
||
1799 | pat.xoffset = 0; |
||
1800 | pat.yoffset = 0; |
||
1801 | m_doc->DoDrawing = false; |
||
1802 | pat.width = ite->width(); |
||
1803 | pat.height = ite->height(); |
||
1804 | pat.items.append(ite); |
||
1805 | m_doc->Items->removeAll(ite); |
||
1806 | QString id = QString("Pattern_from_PDF_%1T").arg(m_doc->docPatterns.count() + 1); |
||
1807 | m_doc->addPattern(id, pat); |
||
1808 | tmpSel->clear(); |
||
1809 | if (m_F3Stack.count() > 0) |
||
1810 | { |
||
1811 | F3Entry f3e = m_F3Stack.pop(); |
||
1812 | m_Font_Pattern_Map.insert(f3e.glyphRef, id); |
||
1813 | state->setCTM(f3e.ctm.m11(), f3e.ctm.m12(), f3e.ctm.m21(), f3e.ctm.m22(), f3e.ctm.dx(), f3e.ctm.dy()); |
||
1814 | QLineF cline = QLineF(0, 0, 1, 0); |
||
1815 | QLineF tline = f3e.ctm.map(cline); |
||
1816 | double xCoor = m_doc->currentPage()->xOffset(); |
||
1817 | double yCoor = m_doc->currentPage()->yOffset(); |
||
1818 | QTransform mm; |
||
1819 | mm.translate(0, -pat.height * tline.length()); |
||
1820 | mm = f3e.ctm * mm; |
||
1821 | int shade = 100; |
||
1822 | CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &shade); |
||
1823 | int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, xCoor + mm.dx(), yCoor + mm.dy(), pat.width * tline.length(), pat.height * tline.length(), 0, CurrColorFill, CommonStrings::None, true); |
||
1824 | PageItem *b = m_doc->Items->at(z); |
||
1825 | b->setWidth(pat.width * tline.length()); |
||
1826 | b->setHeight(pat.height * tline.length()); |
||
1827 | b->OldB2 = b->width(); |
||
1828 | b->OldH2 = b->height(); |
||
1829 | m_doc->RotMode(3); |
||
1830 | m_doc->RotateItem(-tline.angle(), b); |
||
1831 | m_doc->RotMode(0); |
||
1832 | b->setFillShade(shade); |
||
1833 | b->setFillEvenOdd(false); |
||
1834 | b->setFillTransparency(1.0 - state->getFillOpacity()); |
||
1835 | b->setFillBlendmode(getBlendMode(state)); |
||
1836 | b->setLineEnd(PLineEnd); |
||
1837 | b->setLineJoin(PLineJoin); |
||
1838 | b->setTextFlowMode(PageItem::TextFlowDisabled); |
||
1839 | b->setPatternMask(id); |
||
1840 | b->setMaskTransform(b->width() / pat.width * 100, b->height() / pat.height * 100, 0, 0, 0, 0, 0); |
||
1841 | b->setMaskType(3); |
||
1842 | m_Elements->append(b); |
||
1843 | if (m_groupStack.count() != 0) |
||
1844 | { |
||
1845 | m_groupStack.top().Items.append(b); |
||
1846 | } |
||
1847 | } |
||
1848 | } |
||
1849 | } |
||
1850 | |||
1851 | void SlaOutputDev::type3D0(GfxState * /*state*/, double /*wx*/, double /*wy*/) |
||
1852 | { |
||
1853 | } |
||
1854 | |||
1855 | void SlaOutputDev::type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury) |
||
1856 | { |
||
1857 | } |
||
1858 | |||
16729 | fschmid | 1859 | void SlaOutputDev::beginTextObject(GfxState *state) |
1860 | { |
||
16732 | fschmid | 1861 | pushGroup(); |
16729 | fschmid | 1862 | } |
1863 | |||
1864 | void SlaOutputDev::endTextObject(GfxState *state) |
||
1865 | { |
||
1866 | // qDebug() << "End Text Object"; |
||
1867 | if (m_groupStack.count() != 0) |
||
1868 | { |
||
1869 | groupEntry gElements = m_groupStack.pop(); |
||
1870 | tmpSel->clear(); |
||
1871 | if (gElements.Items.count() > 0) |
||
1872 | { |
||
1873 | for (int dre = 0; dre < gElements.Items.count(); ++dre) |
||
1874 | { |
||
1875 | tmpSel->addItem(gElements.Items.at(dre), true); |
||
1876 | m_Elements->removeAll(gElements.Items.at(dre)); |
||
1877 | } |
||
1878 | PageItem *ite = m_doc->groupObjectsSelection(tmpSel); |
||
1879 | ite->setFillTransparency(1.0 - state->getFillOpacity()); |
||
1880 | ite->setFillBlendmode(getBlendMode(state)); |
||
1881 | for (int as = 0; as < tmpSel->count(); ++as) |
||
1882 | { |
||
1883 | m_Elements->append(tmpSel->itemAt(as)); |
||
1884 | } |
||
1885 | if (m_groupStack.count() != 0) |
||
16732 | fschmid | 1886 | applyMask(ite); |
16729 | fschmid | 1887 | } |
1888 | if (m_groupStack.count() != 0) |
||
1889 | { |
||
1890 | for (int as = 0; as < tmpSel->count(); ++as) |
||
1891 | { |
||
1892 | m_groupStack.top().Items.append(tmpSel->itemAt(as)); |
||
1893 | } |
||
1894 | } |
||
1895 | tmpSel->clear(); |
||
1896 | } |
||
1897 | } |
||
1898 | |||
16746 | fschmid | 1899 | QString SlaOutputDev::getColor(GfxColorSpace *color_space, GfxColor *color, int *shade) |
16729 | fschmid | 1900 | { |
1901 | QString fNam; |
||
1902 | QString namPrefix = "FromPDF"; |
||
1903 | ScColor tmp; |
||
1904 | tmp.setSpotColor(false); |
||
1905 | tmp.setRegistrationColor(false); |
||
16746 | fschmid | 1906 | *shade = 100; |
16729 | fschmid | 1907 | if ((color_space->getMode() == csDeviceRGB) || (color_space->getMode() == csCalRGB)) |
1908 | { |
||
1909 | GfxRGB rgb; |
||
1910 | color_space->getRGB(color, &rgb); |
||
1911 | int Rc = qRound(colToDbl(rgb.r) * 255); |
||
1912 | int Gc = qRound(colToDbl(rgb.g) * 255); |
||
1913 | int Bc = qRound(colToDbl(rgb.b) * 255); |
||
1914 | tmp.setColorRGB(Rc, Gc, Bc); |
||
1915 | fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp); |
||
1916 | } |
||
1917 | else if (color_space->getMode() == csDeviceCMYK) |
||
1918 | { |
||
1919 | GfxCMYK cmyk; |
||
1920 | color_space->getCMYK(color, &cmyk); |
||
1921 | int Cc = qRound(colToDbl(cmyk.c) * 255); |
||
1922 | int Mc = qRound(colToDbl(cmyk.m) * 255); |
||
1923 | int Yc = qRound(colToDbl(cmyk.y) * 255); |
||
1924 | int Kc = qRound(colToDbl(cmyk.k) * 255); |
||
1925 | tmp.setColor(Cc, Mc, Yc, Kc); |
||
1926 | fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp); |
||
1927 | } |
||
1928 | else if ((color_space->getMode() == csCalGray) || (color_space->getMode() == csDeviceGray)) |
||
1929 | { |
||
1930 | GfxGray gray; |
||
1931 | color_space->getGray(color, &gray); |
||
1932 | int Kc = 255 - qRound(colToDbl(gray) * 255); |
||
1933 | tmp.setColor(0, 0, 0, Kc); |
||
1934 | fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp); |
||
1935 | } |
||
1936 | else if (color_space->getMode() == csSeparation) |
||
1937 | { |
||
1938 | GfxCMYK cmyk; |
||
1939 | color_space->getCMYK(color, &cmyk); |
||
1940 | int Cc = qRound(colToDbl(cmyk.c) * 255); |
||
1941 | int Mc = qRound(colToDbl(cmyk.m) * 255); |
||
1942 | int Yc = qRound(colToDbl(cmyk.y) * 255); |
||
1943 | int Kc = qRound(colToDbl(cmyk.k) * 255); |
||
1944 | tmp.setColor(Cc, Mc, Yc, Kc); |
||
1945 | tmp.setSpotColor(true); |
||
1946 | QString nam = QString(((GfxSeparationColorSpace*)color_space)->getName()->getCString()); |
||
1947 | fNam = m_doc->PageColors.tryAddColor(nam, tmp); |
||
16746 | fschmid | 1948 | *shade = qRound(colToDbl(color->c[0]) * 100); |
16729 | fschmid | 1949 | } |
1950 | else |
||
1951 | { |
||
1952 | GfxRGB rgb; |
||
1953 | color_space->getRGB(color, &rgb); |
||
1954 | int Rc = qRound(colToDbl(rgb.r) * 255); |
||
1955 | int Gc = qRound(colToDbl(rgb.g) * 255); |
||
1956 | int Bc = qRound(colToDbl(rgb.b) * 255); |
||
1957 | tmp.setColorRGB(Rc, Gc, Bc); |
||
1958 | fNam = m_doc->PageColors.tryAddColor(namPrefix+tmp.name(), tmp); |
||
1959 | // qDebug() << "update fill color other colorspace" << color_space->getMode() << "treating as rgb" << Rc << Gc << Bc; |
||
1960 | } |
||
1961 | if (fNam == namPrefix+tmp.name()) |
||
1962 | m_importedColors->append(fNam); |
||
1963 | return fNam; |
||
1964 | } |
||
1965 | |||
1966 | QString SlaOutputDev::convertPath(GfxPath *path) |
||
1967 | { |
||
1968 | if (! path) |
||
1969 | return QString(); |
||
1970 | |||
1971 | QString output; |
||
1972 | pathIsClosed = false; |
||
1973 | |||
1974 | for (int i = 0; i < path->getNumSubpaths(); ++i) |
||
1975 | { |
||
1976 | GfxSubpath * subpath = path->getSubpath(i); |
||
1977 | if (subpath->getNumPoints() > 0) |
||
1978 | { |
||
1979 | output += QString("M %1 %2").arg(subpath->getX(0)).arg(subpath->getY(0)); |
||
1980 | int j = 1; |
||
1981 | while (j < subpath->getNumPoints()) |
||
1982 | { |
||
1983 | if (subpath->getCurve(j)) |
||
1984 | { |
||
1985 | output += QString("C %1 %2 %3 %4 %5 %6") |
||
1986 | .arg(subpath->getX(j)).arg(subpath->getY(j)) |
||
1987 | .arg(subpath->getX(j + 1)).arg(subpath->getY(j + 1)) |
||
1988 | .arg(subpath->getX(j + 2)).arg(subpath->getY(j + 2)); |
||
1989 | j += 3; |
||
1990 | } |
||
1991 | else |
||
1992 | { |
||
1993 | output += QString("L %1 %2").arg(subpath->getX(j)).arg(subpath->getY(j)); |
||
1994 | ++j; |
||
1995 | } |
||
1996 | } |
||
1997 | if (subpath->isClosed()) |
||
1998 | { |
||
1999 | output += QString("Z"); |
||
2000 | pathIsClosed = true; |
||
2001 | } |
||
2002 | } |
||
2003 | } |
||
2004 | return output; |
||
2005 | } |
||
2006 | |||
2007 | void SlaOutputDev::getPenState(GfxState *state) |
||
2008 | { |
||
2009 | switch (state->getLineCap()) |
||
2010 | { |
||
2011 | case 0: |
||
2012 | PLineEnd = Qt::FlatCap; |
||
2013 | break; |
||
2014 | case 1: |
||
2015 | PLineEnd = Qt::RoundCap; |
||
2016 | break; |
||
2017 | case 2: |
||
2018 | PLineEnd = Qt::SquareCap; |
||
2019 | break; |
||
2020 | } |
||
2021 | switch (state->getLineJoin()) |
||
2022 | { |
||
2023 | case 0: |
||
2024 | PLineJoin = Qt::MiterJoin; |
||
2025 | break; |
||
2026 | case 1: |
||
2027 | PLineJoin = Qt::RoundJoin; |
||
2028 | break; |
||
2029 | case 2: |
||
2030 | PLineJoin = Qt::BevelJoin; |
||
2031 | break; |
||
2032 | } |
||
2033 | double *dashPattern; |
||
2034 | int dashLength; |
||
2035 | state->getLineDash(&dashPattern, &dashLength, &DashOffset); |
||
2036 | QVector<double> pattern(dashLength); |
||
2037 | for (int i = 0; i < dashLength; ++i) |
||
2038 | { |
||
2039 | pattern[i] = dashPattern[i]; |
||
2040 | } |
||
2041 | DashValues = pattern; |
||
2042 | } |
||
2043 | |||
2044 | int SlaOutputDev::getBlendMode(GfxState *state) |
||
2045 | { |
||
2046 | int mode = 0; |
||
2047 | switch (state->getBlendMode()) |
||
2048 | { |
||
2049 | default: |
||
2050 | case gfxBlendNormal: |
||
2051 | mode = 0; |
||
2052 | break; |
||
2053 | case gfxBlendDarken: |
||
2054 | mode = 1; |
||
2055 | break; |
||
2056 | case gfxBlendLighten: |
||
2057 | mode = 2; |
||
2058 | break; |
||
2059 | case gfxBlendMultiply: |
||
2060 | mode = 3; |
||
2061 | break; |
||
2062 | case gfxBlendScreen: |
||
2063 | mode = 4; |
||
2064 | break; |
||
2065 | case gfxBlendOverlay: |
||
2066 | mode = 5; |
||
2067 | break; |
||
2068 | case gfxBlendHardLight: |
||
2069 | mode = 6; |
||
2070 | break; |
||
2071 | case gfxBlendSoftLight: |
||
2072 | mode = 7; |
||
2073 | break; |
||
2074 | case gfxBlendDifference: |
||
2075 | mode = 8; |
||
2076 | break; |
||
2077 | case gfxBlendExclusion: |
||
2078 | mode = 9; |
||
2079 | break; |
||
2080 | case gfxBlendColorDodge: |
||
2081 | mode = 10; |
||
2082 | break; |
||
2083 | case gfxBlendColorBurn: |
||
2084 | mode = 11; |
||
2085 | break; |
||
2086 | case gfxBlendHue: |
||
2087 | mode = 12; |
||
2088 | break; |
||
2089 | case gfxBlendSaturation: |
||
2090 | mode = 13; |
||
2091 | break; |
||
2092 | case gfxBlendColor: |
||
2093 | mode = 14; |
||
2094 | break; |
||
2095 | case gfxBlendLuminosity: |
||
2096 | mode = 15; |
||
2097 | break; |
||
2098 | } |
||
2099 | return mode; |
||
2100 | } |
||
2101 | |||
16732 | fschmid | 2102 | void SlaOutputDev::applyMask(PageItem *ite) |
2103 | { |
||
2104 | if (m_groupStack.count() != 0) |
||
2105 | { |
||
2106 | if (!m_groupStack.top().maskName.isEmpty()) |
||
2107 | { |
||
2108 | ite->setPatternMask(m_groupStack.top().maskName); |
||
2109 | if (m_groupStack.top().alpha) |
||
2110 | { |
||
2111 | if (m_groupStack.top().inverted) |
||
2112 | ite->setMaskType(8); |
||
2113 | else |
||
2114 | ite->setMaskType(3); |
||
2115 | } |
||
2116 | else |
||
2117 | { |
||
2118 | if (m_groupStack.top().inverted) |
||
2119 | ite->setMaskType(7); |
||
2120 | else |
||
2121 | ite->setMaskType(6); |
||
2122 | } |
||
2123 | } |
||
2124 | } |
||
2125 | } |
||
2126 | |||
2127 | void SlaOutputDev::pushGroup(QString maskName, GBool forSoftMask, GBool alpha, bool inverted) |
||
2128 | { |
||
2129 | groupEntry gElements; |
||
2130 | gElements.forSoftMask = forSoftMask; |
||
2131 | gElements.alpha = alpha; |
||
2132 | gElements.inverted = inverted; |
||
2133 | gElements.maskName = maskName; |
||
2134 | m_groupStack.push(gElements); |