source: trunk/src/svg/qsvgstyle.cpp@ 13

Last change on this file since 13 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 20.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information (qt-info@nokia.com)
5**
6** This file is part of the QtSvg module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at qt-sales@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qsvgstyle_p.h"
43
44#ifndef QT_NO_SVG
45
46#include "qsvgfont_p.h"
47#include "qsvggraphics_p.h"
48#include "qsvgnode_p.h"
49#include "qsvgtinydocument_p.h"
50
51#include "qpainter.h"
52#include "qpair.h"
53#include "qcolor.h"
54#include "qdebug.h"
55#include "qmath.h"
56#include "qnumeric.h"
57
58QT_BEGIN_NAMESPACE
59
60QSvgExtraStates::QSvgExtraStates()
61 : fillOpacity(1.0)
62{
63}
64
65QSvgStyleProperty::~QSvgStyleProperty()
66{
67}
68
69QSvgQualityStyle::QSvgQualityStyle(int color)
70 : m_colorRendering(color)
71{
72
73}
74void QSvgQualityStyle::apply(QPainter *, const QRectF &, QSvgNode *, QSvgExtraStates &)
75{
76
77}
78void QSvgQualityStyle::revert(QPainter *, QSvgExtraStates &)
79{
80
81}
82
83QSvgFillStyle::QSvgFillStyle(const QBrush &brush)
84 : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillOpacitySet(false)
85{
86}
87
88QSvgFillStyle::QSvgFillStyle(QSvgStyleProperty *style)
89 : m_style(style), m_fillRuleSet(false), m_fillOpacitySet(false)
90{
91}
92
93void QSvgFillStyle::setFillRule(Qt::FillRule f)
94{
95 m_fillRuleSet = true;
96 m_fillRule = f;
97}
98
99void QSvgFillStyle::setFillOpacity(qreal opacity)
100{
101 m_fillOpacitySet = true;
102 m_fillOpacity = opacity;
103}
104
105static void recursivelySetFill(QSvgNode *node, Qt::FillRule f)
106{
107 if (node->type() == QSvgNode::PATH) {
108 QSvgPath *path = static_cast<QSvgPath*>(node);
109 path->qpath()->setFillRule(f);
110 } else if (node->type() == QSvgNode::G) {
111 QList<QSvgNode*> renderers = static_cast<QSvgG*>(node)->renderers();
112 foreach(QSvgNode *n, renderers) {
113 recursivelySetFill(n, f);
114 }
115 }
116}
117void QSvgFillStyle::apply(QPainter *p, const QRectF &rect, QSvgNode *node, QSvgExtraStates &states)
118{
119 m_oldFill = p->brush();
120 m_oldOpacity = states.fillOpacity;
121
122 if (m_fillRuleSet) {
123 recursivelySetFill(node, m_fillRule);
124 m_fillRuleSet = false;//set it only on the first run
125 }
126 p->setBrush(m_fill);
127 if (m_fillOpacitySet)
128 states.fillOpacity = m_fillOpacity;
129 if (m_style)
130 m_style->apply(p, rect, node, states);
131}
132
133void QSvgFillStyle::revert(QPainter *p, QSvgExtraStates &states)
134{
135 if (m_style)
136 m_style->revert(p, states);
137 p->setBrush(m_oldFill);
138 if (m_fillOpacitySet)
139 states.fillOpacity = m_oldOpacity;
140}
141
142QSvgViewportFillStyle::QSvgViewportFillStyle(const QBrush &brush)
143 : m_viewportFill(brush)
144{
145}
146
147void QSvgViewportFillStyle::apply(QPainter *p, const QRectF &, QSvgNode *, QSvgExtraStates &)
148{
149 m_oldFill = p->brush();
150 p->setBrush(m_viewportFill);
151}
152
153void QSvgViewportFillStyle::revert(QPainter *p, QSvgExtraStates &)
154{
155 p->setBrush(m_oldFill);
156}
157
158QSvgFontStyle::QSvgFontStyle(QSvgFont *font, QSvgTinyDocument *doc)
159 : m_font(font), m_pointSize(24), m_doc(doc)
160{
161}
162
163QSvgFontStyle::QSvgFontStyle(const QFont &font, QSvgTinyDocument *doc)
164 : m_font(0), m_pointSize(24), m_doc(doc), m_qfont(font)
165{
166}
167
168
169void QSvgFontStyle::setPointSize(qreal size)
170{
171 m_pointSize = size;
172}
173
174qreal QSvgFontStyle::pointSize() const
175{
176 return m_pointSize;
177}
178
179void QSvgFontStyle::apply(QPainter *p, const QRectF &, QSvgNode *, QSvgExtraStates &)
180{
181 if (!m_font) {
182 m_oldFont = p->font();
183 p->setFont(m_qfont);
184 }
185}
186
187void QSvgFontStyle::revert(QPainter *p, QSvgExtraStates &)
188{
189 if (!m_font) {
190 p->setFont(m_oldFont);
191 }
192}
193
194QSvgStrokeStyle::QSvgStrokeStyle(const QPen &pen)
195 : m_stroke(pen)
196{
197}
198
199void QSvgStrokeStyle::apply(QPainter *p, const QRectF &, QSvgNode *, QSvgExtraStates &)
200{
201 m_oldStroke = p->pen();
202 p->setPen(m_stroke);
203}
204
205void QSvgStrokeStyle::revert(QPainter *p, QSvgExtraStates &)
206{
207 p->setPen(m_oldStroke);
208}
209
210QSvgSolidColorStyle::QSvgSolidColorStyle(const QColor &color)
211 : m_solidColor(color)
212{
213}
214
215void QSvgSolidColorStyle::apply(QPainter *p, const QRectF &, QSvgNode *, QSvgExtraStates &)
216{
217 m_oldFill = p->brush();
218 m_oldStroke = p->pen();
219 QBrush b = m_oldFill;
220 b.setColor(m_solidColor);
221 p->setBrush(b);
222 QPen pen = m_oldStroke;
223 pen.setColor(m_solidColor);
224 p->setPen(pen);
225}
226
227void QSvgSolidColorStyle::revert(QPainter *p, QSvgExtraStates &)
228{
229 p->setBrush(m_oldFill);
230 p->setPen(m_oldStroke);
231}
232
233QSvgGradientStyle::QSvgGradientStyle(QGradient *grad)
234 : m_gradient(grad), m_gradientStopsSet(false)
235{
236}
237
238void QSvgGradientStyle::apply(QPainter *p, const QRectF &/*rect*/, QSvgNode *, QSvgExtraStates &)
239{
240 if (!m_link.isEmpty()) {
241 resolveStops();
242 }
243
244 m_oldFill = p->brush();
245
246 //resolving stop colors
247 if (!m_resolvePoints.isEmpty()) {
248 QColor color = p->brush().color();
249 if (!color.isValid())
250 color = p->pen().color();
251 QList<qreal>::const_iterator itr = m_resolvePoints.constBegin();
252 for (; itr != m_resolvePoints.constEnd(); ++itr) {
253 //qDebug()<<"resolving "<<(*itr)<<" to "<<color;
254 m_gradient->setColorAt(*itr, color);
255 }
256 }
257
258 // If the gradient is marked as empty, insert transparent black
259 if (!m_gradientStopsSet) {
260 m_gradient->setStops(QGradientStops() << QGradientStop(0.0, QColor(0, 0, 0, 0)));
261 m_gradientStopsSet = true;
262 }
263
264 QBrush brush;
265 brush = QBrush(*m_gradient);
266
267 if (!m_matrix.isIdentity())
268 brush.setMatrix(m_matrix);
269
270 p->setBrush(brush);
271}
272
273void QSvgGradientStyle::revert(QPainter *p, QSvgExtraStates &)
274{
275 p->setBrush(m_oldFill);
276}
277
278
279void QSvgGradientStyle::setMatrix(const QMatrix &mat)
280{
281 m_matrix = mat;
282}
283
284void QSvgGradientStyle::addResolve(qreal offset)
285{
286 m_resolvePoints.append(offset);
287}
288
289QSvgTransformStyle::QSvgTransformStyle(const QTransform &trans)
290 : m_transform(trans)
291{
292}
293
294void QSvgTransformStyle::apply(QPainter *p, const QRectF &, QSvgNode *, QSvgExtraStates &)
295{
296 m_oldWorldTransform = p->worldTransform();
297 p->setWorldTransform(m_transform, true);
298}
299
300void QSvgTransformStyle::revert(QPainter *p, QSvgExtraStates &)
301{
302 p->setWorldTransform(m_oldWorldTransform, false /* don't combine */);
303}
304
305QSvgStyleProperty::Type QSvgQualityStyle::type() const
306{
307 return QUALITY;
308}
309
310QSvgStyleProperty::Type QSvgFillStyle::type() const
311{
312 return FILL;
313}
314
315QSvgStyleProperty::Type QSvgViewportFillStyle::type() const
316{
317 return VIEWPORT_FILL;
318}
319
320QSvgStyleProperty::Type QSvgFontStyle::type() const
321{
322 return FONT;
323}
324
325QSvgStyleProperty::Type QSvgStrokeStyle::type() const
326{
327 return STROKE;
328}
329
330QSvgStyleProperty::Type QSvgSolidColorStyle::type() const
331{
332 return SOLID_COLOR;
333}
334
335QSvgStyleProperty::Type QSvgGradientStyle::type() const
336{
337 return GRADIENT;
338}
339
340QSvgStyleProperty::Type QSvgTransformStyle::type() const
341{
342 return TRANSFORM;
343}
344
345
346QSvgCompOpStyle::QSvgCompOpStyle(QPainter::CompositionMode mode)
347 : m_mode(mode)
348{
349
350}
351
352void QSvgCompOpStyle::apply(QPainter *p, const QRectF &, QSvgNode *, QSvgExtraStates &)
353{
354 m_oldMode = p->compositionMode();
355 p->setCompositionMode(m_mode);
356}
357
358void QSvgCompOpStyle::revert(QPainter *p, QSvgExtraStates &)
359{
360 p->setCompositionMode(m_oldMode);
361}
362
363QSvgStyleProperty::Type QSvgCompOpStyle::type() const
364{
365 return COMP_OP;
366}
367
368QSvgStyle::~QSvgStyle()
369{
370}
371
372void QSvgStyle::apply(QPainter *p, const QRectF &rect, QSvgNode *node, QSvgExtraStates &states)
373{
374 if (quality) {
375 quality->apply(p, rect, node, states);
376 }
377
378 if (fill) {
379 fill->apply(p, rect, node, states);
380 }
381
382 if (viewportFill) {
383 viewportFill->apply(p, rect, node, states);
384 }
385
386 if (font) {
387 font->apply(p, rect, node, states);
388 }
389
390 if (stroke) {
391 stroke->apply(p, rect, node, states);
392 }
393
394 if (solidColor) {
395 solidColor->apply(p, rect, node, states);
396 }
397
398 if (gradient) {
399 gradient->apply(p, rect, node, states);
400 }
401
402 if (transform) {
403 transform->apply(p, rect, node, states);
404 }
405
406 if (animateColor) {
407 animateColor->apply(p, rect, node, states);
408 }
409
410 //animated transforms have to be applied
411 //_after_ the original object transformations
412 if (!animateTransforms.isEmpty()) {
413 QList<QSvgRefCounter<QSvgAnimateTransform> >::const_iterator itr;
414 for (itr = animateTransforms.constBegin(); itr != animateTransforms.constEnd();
415 ++itr) {
416 (*itr)->apply(p, rect, node, states);
417 }
418 }
419
420 if (opacity) {
421 opacity->apply(p, rect, node, states);
422 }
423
424 if (compop) {
425 compop->apply(p, rect, node, states);
426 }
427}
428
429void QSvgStyle::revert(QPainter *p, QSvgExtraStates &states)
430{
431 if (quality) {
432 quality->revert(p, states);
433 }
434
435 if (fill) {
436 fill->revert(p, states);
437 }
438
439 if (viewportFill) {
440 viewportFill->revert(p, states);
441 }
442
443 if (font) {
444 font->revert(p, states);
445 }
446
447 if (stroke) {
448 stroke->revert(p, states);
449 }
450
451 if (solidColor) {
452 solidColor->revert(p, states);
453 }
454
455 if (gradient) {
456 gradient->revert(p, states);
457 }
458
459 //animated transforms need to be reverted _before_
460 //the native transforms
461 if (!animateTransforms.isEmpty()) {
462 QList<QSvgRefCounter<QSvgAnimateTransform> >::const_iterator itr;
463 itr = animateTransforms.constBegin();
464 //only need to rever the first one because that
465 //one has the original world matrix for the primitve
466 if (itr != animateTransforms.constEnd()) {
467 (*itr)->revert(p, states);
468 }
469 }
470
471 if (transform) {
472 transform->revert(p, states);
473 }
474
475 if (animateColor) {
476 animateColor->revert(p, states);
477 }
478
479 if (opacity) {
480 opacity->revert(p, states);
481 }
482
483 if (compop) {
484 compop->revert(p, states);
485 }
486}
487
488QSvgAnimateTransform::QSvgAnimateTransform(int startMs, int endMs, int byMs )
489 : QSvgStyleProperty(),
490 m_from(startMs), m_to(endMs), m_by(byMs),
491 m_type(Empty), m_count(0), m_finished(false)
492{
493 m_totalRunningTime = m_to - m_from;
494}
495
496void QSvgAnimateTransform::setArgs(TransformType type, const QVector<qreal> &args)
497{
498 m_type = type;
499 m_args = args;
500 Q_ASSERT(!(args.count()%3));
501 m_count = args.count() / 3;
502}
503
504void QSvgAnimateTransform::apply(QPainter *p, const QRectF &, QSvgNode *node, QSvgExtraStates &)
505{
506 m_oldWorldTransform = p->worldTransform();
507 resolveMatrix(node);
508 if (!m_finished || m_freeze)
509 p->setWorldTransform(m_transform, true);
510}
511
512void QSvgAnimateTransform::revert(QPainter *p, QSvgExtraStates &)
513{
514 if (!m_finished || m_freeze) {
515 p->setWorldTransform(m_oldWorldTransform, false /* don't combine */);
516 }
517}
518
519void QSvgAnimateTransform::resolveMatrix(QSvgNode *node)
520{
521 static const qreal deg2rad = qreal(0.017453292519943295769);
522 qreal totalTimeElapsed = node->document()->currentElapsed();
523 if (totalTimeElapsed < m_from || m_finished)
524 return;
525
526 qreal animationFrame = (totalTimeElapsed - m_from) / m_to;
527
528 if (m_repeatCount >= 0 && m_repeatCount < animationFrame) {
529 m_finished = true;
530 animationFrame = m_repeatCount;
531 }
532
533 qreal percentOfAnimation = animationFrame;
534 if (percentOfAnimation > 1) {
535 percentOfAnimation -= ((int)percentOfAnimation);
536 }
537
538 qreal currentPosition = percentOfAnimation * (m_count - 1);
539 int startElem = qFloor(currentPosition);
540 int endElem = qCeil(currentPosition);
541
542 switch(m_type)
543 {
544 case Translate: {
545 startElem *= 3;
546 endElem *= 3;
547 qreal from1, from2, from3;
548 qreal to1, to2, to3;
549 from1 = m_args[startElem++];
550 from2 = m_args[startElem++];
551 from3 = m_args[startElem++];
552 to1 = m_args[endElem++];
553 to2 = m_args[endElem++];
554 to3 = m_args[endElem++];
555
556 qreal transXDiff = (to1-from1) * percentOfAnimation;
557 qreal transX = from1 + transXDiff;
558 qreal transYDiff = (to2-from2) * percentOfAnimation;
559 qreal transY = from2 + transYDiff;
560 m_transform = QTransform();
561 m_transform.translate(transX, transY);
562 break;
563 }
564 case Scale: {
565 startElem *= 3;
566 endElem *= 3;
567 qreal from1, from2, from3;
568 qreal to1, to2, to3;
569 from1 = m_args[startElem++];
570 from2 = m_args[startElem++];
571 from3 = m_args[startElem++];
572 to1 = m_args[endElem++];
573 to2 = m_args[endElem++];
574 to3 = m_args[endElem++];
575
576 qreal transXDiff = (to1-from1) * percentOfAnimation;
577 qreal transX = from1 + transXDiff;
578 qreal transYDiff = (to2-from2) * percentOfAnimation;
579 qreal transY = from2 + transYDiff;
580 if (transY == 0)
581 transY = transX;
582 m_transform = QTransform();
583 m_transform.scale(transX, transY);
584 break;
585 }
586 case Rotate: {
587 startElem *= 3;
588 endElem *= 3;
589 qreal from1, from2, from3;
590 qreal to1, to2, to3;
591 from1 = m_args[startElem++];
592 from2 = m_args[startElem++];
593 from3 = m_args[startElem++];
594 to1 = m_args[endElem++];
595 to2 = m_args[endElem++];
596 to3 = m_args[endElem++];
597
598 qreal rotationDiff = (to1 - from1) * percentOfAnimation;
599 //qreal rotation = from1 + rotationDiff;
600
601 qreal transXDiff = (to2-from2) * percentOfAnimation;
602 qreal transX = from2 + transXDiff;
603 qreal transYDiff = (to3-from3) * percentOfAnimation;
604 qreal transY = from3 + transYDiff;
605 m_transform = QTransform();
606 m_transform.translate(transX, transY);
607 m_transform.rotate(rotationDiff);
608 m_transform.translate(-transX, -transY);
609 break;
610 }
611 case SkewX: {
612 startElem *= 3;
613 endElem *= 3;
614 qreal from1, from2, from3;
615 qreal to1, to2, to3;
616 from1 = m_args[startElem++];
617 from2 = m_args[startElem++];
618 from3 = m_args[startElem++];
619 to1 = m_args[endElem++];
620 to2 = m_args[endElem++];
621 to3 = m_args[endElem++];
622
623 qreal transXDiff = (to1-from1) * percentOfAnimation;
624 qreal transX = from1 + transXDiff;
625 m_transform = QTransform();
626 m_transform.shear(tan(transX * deg2rad), 0);
627 break;
628 }
629 case SkewY: {
630 startElem *= 3;
631 endElem *= 3;
632 qreal from1, from2, from3;
633 qreal to1, to2, to3;
634 from1 = m_args[startElem++];
635 from2 = m_args[startElem++];
636 from3 = m_args[startElem++];
637 to1 = m_args[endElem++];
638 to2 = m_args[endElem++];
639 to3 = m_args[endElem++];
640
641
642 qreal transYDiff = (to1 - from1) * percentOfAnimation;
643 qreal transY = from1 + transYDiff;
644 m_transform = QTransform();
645 m_transform.shear(0, tan(transY * deg2rad));
646 break;
647 }
648 default:
649 break;
650 }
651}
652
653QSvgStyleProperty::Type QSvgAnimateTransform::type() const
654{
655 return ANIMATE_TRANSFORM;
656}
657
658void QSvgAnimateTransform::setFreeze(bool freeze)
659{
660 m_freeze = freeze;
661}
662
663void QSvgAnimateTransform::setRepeatCount(qreal repeatCount)
664{
665 m_repeatCount = repeatCount;
666}
667
668QSvgAnimateColor::QSvgAnimateColor(int startMs, int endMs, int byMs)
669 : QSvgStyleProperty(),
670 m_from(startMs), m_to(endMs), m_by(byMs),
671 m_finished(false)
672{
673 m_totalRunningTime = m_to - m_from;
674}
675
676void QSvgAnimateColor::setArgs(bool fill,
677 const QList<QColor> &colors)
678{
679 m_fill = fill;
680 m_colors = colors;
681}
682
683void QSvgAnimateColor::setFreeze(bool freeze)
684{
685 m_freeze = freeze;
686}
687
688void QSvgAnimateColor::setRepeatCount(qreal repeatCount)
689{
690 m_repeatCount = repeatCount;
691}
692
693void QSvgAnimateColor::apply(QPainter *p, const QRectF &, QSvgNode *node, QSvgExtraStates &)
694{
695 qreal totalTimeElapsed = node->document()->currentElapsed();
696 if (totalTimeElapsed < m_from || m_finished)
697 return;
698
699 qreal animationFrame = (totalTimeElapsed - m_from) / m_to;
700
701 if (m_repeatCount >= 0 && m_repeatCount < animationFrame) {
702 m_finished = true;
703 animationFrame = m_repeatCount;
704 }
705
706 qreal percentOfAnimation = animationFrame;
707 if (percentOfAnimation > 1) {
708 percentOfAnimation -= ((int)percentOfAnimation);
709 }
710
711 qreal currentPosition = percentOfAnimation * (m_colors.count() - 1);
712
713 int startElem = qFloor(currentPosition);
714 int endElem = qCeil(currentPosition);
715 QColor start = m_colors[startElem];
716 QColor end = m_colors[endElem];
717
718 qreal percentOfColorMorph = currentPosition;
719 if (percentOfColorMorph > 1) {
720 percentOfColorMorph -= ((int)percentOfColorMorph);
721 }
722
723 // Interpolate between the two fixed colors start and end
724 qreal aDiff = (end.alpha() - start.alpha()) * percentOfColorMorph;
725 qreal rDiff = (end.red() - start.red()) * percentOfColorMorph;
726 qreal gDiff = (end.green() - start.green()) * percentOfColorMorph;
727 qreal bDiff = (end.blue() - start.blue()) * percentOfColorMorph;
728
729 int alpha = int(start.alpha() + aDiff);
730 int red = int(start.red() + rDiff);
731 int green = int(start.green() + gDiff);
732 int blue = int(start.blue() + bDiff);
733
734 QColor color(red, green, blue, alpha);
735
736 if (m_fill) {
737 QBrush b = p->brush();
738 m_oldBrush = b;
739 b.setColor(color);
740 p->setBrush(b);
741 } else {
742 QPen pen = p->pen();
743 m_oldPen = pen;
744 pen.setColor(color);
745 p->setPen(pen);
746 }
747}
748
749void QSvgAnimateColor::revert(QPainter *p, QSvgExtraStates &)
750{
751 if (m_fill) {
752 p->setBrush(m_oldBrush);
753 } else {
754 p->setPen(m_oldPen);
755 }
756}
757
758QSvgStyleProperty::Type QSvgAnimateColor::type() const
759{
760 return ANIMATE_COLOR;
761}
762
763QString QSvgFontStyle::textAnchor() const
764{
765 return m_textAnchor;
766}
767
768void QSvgFontStyle::setTextAnchor(const QString &anchor)
769{
770 m_textAnchor = anchor;
771}
772
773QSvgOpacityStyle::QSvgOpacityStyle(qreal opacity)
774 : m_opacity(opacity)
775{
776
777}
778
779void QSvgOpacityStyle::apply(QPainter *p, const QRectF &, QSvgNode *, QSvgExtraStates &)
780{
781 m_oldOpacity = p->opacity();
782 p->setOpacity(m_opacity * m_oldOpacity);
783}
784
785void QSvgOpacityStyle::revert(QPainter *p, QSvgExtraStates &)
786{
787 p->setOpacity(m_oldOpacity);
788}
789
790QSvgStyleProperty::Type QSvgOpacityStyle::type() const
791{
792 return OPACITY;
793}
794
795void QSvgGradientStyle::setStopLink(const QString &link, QSvgTinyDocument *doc)
796{
797 m_link = link;
798 m_doc = doc;
799}
800
801void QSvgGradientStyle::resolveStops()
802{
803 if (!m_link.isEmpty() && m_doc) {
804 QSvgStyleProperty *prop = m_doc->scopeStyle(m_link);
805 if (prop) {
806 if (prop->type() == QSvgStyleProperty::GRADIENT) {
807 QSvgGradientStyle *st =
808 static_cast<QSvgGradientStyle*>(prop);
809 st->resolveStops();
810 m_gradient->setStops(st->qgradient()->stops());
811 }
812 }
813 m_link = QString();
814 }
815}
816
817QT_END_NAMESPACE
818
819#endif // QT_NO_SVG
Note: See TracBrowser for help on using the repository browser.