76 void QSvgAnimation::draw(QPainter *, QSvgExtraStates &) |
76 void QSvgAnimation::draw(QPainter *, QSvgExtraStates &) |
77 { |
77 { |
78 qWarning("<animation> no implemented"); |
78 qWarning("<animation> no implemented"); |
79 } |
79 } |
80 |
80 |
81 static inline QRectF boundsOnStroke(const QPainterPath &path, qreal width) |
81 static inline QRectF boundsOnStroke(QPainter *p, const QPainterPath &path, qreal width) |
82 { |
82 { |
83 QPainterPathStroker stroker; |
83 QPainterPathStroker stroker; |
84 stroker.setWidth(width); |
84 stroker.setWidth(width); |
85 QPainterPath stroke = stroker.createStroke(path); |
85 QPainterPath stroke = stroker.createStroke(path); |
86 return stroke.boundingRect(); |
86 return p->transform().map(stroke).boundingRect(); |
87 } |
87 } |
88 |
88 |
89 QSvgCircle::QSvgCircle(QSvgNode *parent, const QRectF &rect) |
89 QSvgEllipse::QSvgEllipse(QSvgNode *parent, const QRectF &rect) |
90 : QSvgNode(parent), m_bounds(rect) |
90 : QSvgNode(parent), m_bounds(rect) |
91 { |
91 { |
92 } |
92 } |
93 |
93 |
94 |
94 |
95 QRectF QSvgCircle::bounds() const |
95 QRectF QSvgEllipse::bounds(QPainter *p, QSvgExtraStates &) const |
96 { |
96 { |
97 qreal sw = strokeWidth(); |
97 QPainterPath path; |
98 if (qFuzzyIsNull(sw)) |
98 path.addEllipse(m_bounds); |
99 return m_bounds; |
99 qreal sw = strokeWidth(p); |
100 else { |
100 return qFuzzyIsNull(sw) ? p->transform().map(path).boundingRect() : boundsOnStroke(p, path, sw); |
101 QPainterPath path; |
101 } |
102 path.addRect(m_bounds); |
102 |
103 return boundsOnStroke(path, sw); |
103 void QSvgEllipse::draw(QPainter *p, QSvgExtraStates &states) |
104 } |
|
105 } |
|
106 |
|
107 void QSvgCircle::draw(QPainter *p, QSvgExtraStates &states) |
|
108 { |
104 { |
109 applyStyle(p, states); |
105 applyStyle(p, states); |
110 QT_SVG_DRAW_SHAPE(p->drawEllipse(m_bounds)); |
106 QT_SVG_DRAW_SHAPE(p->drawEllipse(m_bounds)); |
111 revertStyle(p, states); |
107 revertStyle(p, states); |
112 } |
108 } |
113 |
109 |
114 QSvgArc::QSvgArc(QSvgNode *parent, const QPainterPath &path) |
110 QSvgArc::QSvgArc(QSvgNode *parent, const QPainterPath &path) |
115 : QSvgNode(parent), cubic(path) |
111 : QSvgNode(parent), m_path(path) |
116 { |
112 { |
117 m_cachedBounds = path.boundingRect(); |
|
118 } |
113 } |
119 |
114 |
120 void QSvgArc::draw(QPainter *p, QSvgExtraStates &states) |
115 void QSvgArc::draw(QPainter *p, QSvgExtraStates &states) |
121 { |
116 { |
122 applyStyle(p, states); |
117 applyStyle(p, states); |
123 if (p->pen().widthF() != 0) { |
118 if (p->pen().widthF() != 0) { |
124 qreal oldOpacity = p->opacity(); |
119 qreal oldOpacity = p->opacity(); |
125 p->setOpacity(oldOpacity * states.strokeOpacity); |
120 p->setOpacity(oldOpacity * states.strokeOpacity); |
126 p->drawPath(cubic); |
121 p->drawPath(m_path); |
127 p->setOpacity(oldOpacity); |
122 p->setOpacity(oldOpacity); |
128 } |
123 } |
129 revertStyle(p, states); |
|
130 } |
|
131 |
|
132 QSvgEllipse::QSvgEllipse(QSvgNode *parent, const QRectF &rect) |
|
133 : QSvgNode(parent), m_bounds(rect) |
|
134 { |
|
135 } |
|
136 |
|
137 QRectF QSvgEllipse::bounds() const |
|
138 { |
|
139 qreal sw = strokeWidth(); |
|
140 if (qFuzzyIsNull(sw)) |
|
141 return m_bounds; |
|
142 else { |
|
143 QPainterPath path; |
|
144 path.addEllipse(m_bounds); |
|
145 return boundsOnStroke(path, sw); |
|
146 } |
|
147 } |
|
148 |
|
149 void QSvgEllipse::draw(QPainter *p, QSvgExtraStates &states) |
|
150 { |
|
151 applyStyle(p, states); |
|
152 QT_SVG_DRAW_SHAPE(p->drawEllipse(m_bounds)); |
|
153 revertStyle(p, states); |
124 revertStyle(p, states); |
154 } |
125 } |
155 |
126 |
156 QSvgImage::QSvgImage(QSvgNode *parent, const QImage &image, |
127 QSvgImage::QSvgImage(QSvgNode *parent, const QImage &image, |
157 const QRect &bounds) |
128 const QRect &bounds) |
171 revertStyle(p, states); |
142 revertStyle(p, states); |
172 } |
143 } |
173 |
144 |
174 |
145 |
175 QSvgLine::QSvgLine(QSvgNode *parent, const QLineF &line) |
146 QSvgLine::QSvgLine(QSvgNode *parent, const QLineF &line) |
176 : QSvgNode(parent), m_bounds(line) |
147 : QSvgNode(parent), m_line(line) |
177 { |
148 { |
178 } |
149 } |
179 |
150 |
180 |
151 |
181 void QSvgLine::draw(QPainter *p, QSvgExtraStates &states) |
152 void QSvgLine::draw(QPainter *p, QSvgExtraStates &states) |
182 { |
153 { |
183 applyStyle(p, states); |
154 applyStyle(p, states); |
184 if (p->pen().widthF() != 0) { |
155 if (p->pen().widthF() != 0) { |
185 qreal oldOpacity = p->opacity(); |
156 qreal oldOpacity = p->opacity(); |
186 p->setOpacity(oldOpacity * states.strokeOpacity); |
157 p->setOpacity(oldOpacity * states.strokeOpacity); |
187 p->drawLine(m_bounds); |
158 p->drawLine(m_line); |
188 p->setOpacity(oldOpacity); |
159 p->setOpacity(oldOpacity); |
189 } |
160 } |
190 revertStyle(p, states); |
161 revertStyle(p, states); |
191 } |
162 } |
192 |
163 |
201 m_path.setFillRule(states.fillRule); |
172 m_path.setFillRule(states.fillRule); |
202 QT_SVG_DRAW_SHAPE(p->drawPath(m_path)); |
173 QT_SVG_DRAW_SHAPE(p->drawPath(m_path)); |
203 revertStyle(p, states); |
174 revertStyle(p, states); |
204 } |
175 } |
205 |
176 |
206 QRectF QSvgPath::bounds() const |
177 QRectF QSvgPath::bounds(QPainter *p, QSvgExtraStates &) const |
207 { |
178 { |
208 qreal sw = strokeWidth(); |
179 qreal sw = strokeWidth(p); |
209 if (qFuzzyIsNull(sw)) { |
180 return qFuzzyIsNull(sw) ? p->transform().map(m_path).boundingRect() |
210 if (m_cachedBounds.isNull()) |
181 : boundsOnStroke(p, m_path, sw); |
211 //m_cachedBounds = m_path.controlPointRect(); |
|
212 m_cachedBounds = m_path.boundingRect(); |
|
213 |
|
214 return m_cachedBounds; |
|
215 } |
|
216 else { |
|
217 return boundsOnStroke(m_path, sw); |
|
218 } |
|
219 } |
182 } |
220 |
183 |
221 QSvgPolygon::QSvgPolygon(QSvgNode *parent, const QPolygonF &poly) |
184 QSvgPolygon::QSvgPolygon(QSvgNode *parent, const QPolygonF &poly) |
222 : QSvgNode(parent), m_poly(poly) |
185 : QSvgNode(parent), m_poly(poly) |
223 { |
186 { |
224 } |
187 } |
225 |
188 |
226 QRectF QSvgPolygon::bounds() const |
189 QRectF QSvgPolygon::bounds(QPainter *p, QSvgExtraStates &) const |
227 { |
190 { |
228 qreal sw = strokeWidth(); |
191 qreal sw = strokeWidth(p); |
229 if (qFuzzyIsNull(sw)) |
192 if (qFuzzyIsNull(sw)) { |
230 return m_poly.boundingRect(); |
193 return p->transform().map(m_poly).boundingRect(); |
231 else { |
194 } else { |
232 QPainterPath path; |
195 QPainterPath path; |
233 path.addPolygon(m_poly); |
196 path.addPolygon(m_poly); |
234 return boundsOnStroke(path, sw); |
197 return boundsOnStroke(p, path, sw); |
235 } |
198 } |
236 } |
199 } |
237 |
200 |
238 void QSvgPolygon::draw(QPainter *p, QSvgExtraStates &states) |
201 void QSvgPolygon::draw(QPainter *p, QSvgExtraStates &states) |
239 { |
202 { |
272 : QSvgNode(node), |
235 : QSvgNode(node), |
273 m_rect(rect), m_rx(rx), m_ry(ry) |
236 m_rect(rect), m_rx(rx), m_ry(ry) |
274 { |
237 { |
275 } |
238 } |
276 |
239 |
277 QRectF QSvgRect::bounds() const |
240 QRectF QSvgRect::bounds(QPainter *p, QSvgExtraStates &) const |
278 { |
241 { |
279 qreal sw = strokeWidth(); |
242 qreal sw = strokeWidth(p); |
280 if (qFuzzyIsNull(sw)) |
243 if (qFuzzyIsNull(sw)) { |
281 return m_rect; |
244 return p->transform().mapRect(m_rect); |
282 else { |
245 } else { |
283 QPainterPath path; |
246 QPainterPath path; |
284 path.addRect(m_rect); |
247 path.addRect(m_rect); |
285 return boundsOnStroke(path, sw); |
248 return boundsOnStroke(p, path, sw); |
286 } |
249 } |
287 } |
250 } |
288 |
251 |
289 void QSvgRect::draw(QPainter *p, QSvgExtraStates &states) |
252 void QSvgRect::draw(QPainter *p, QSvgExtraStates &states) |
290 { |
253 { |
591 QSvgNode::Type QSvgVideo::type() const |
554 QSvgNode::Type QSvgVideo::type() const |
592 { |
555 { |
593 return VIDEO; |
556 return VIDEO; |
594 } |
557 } |
595 |
558 |
596 QRectF QSvgUse::bounds() const |
559 QRectF QSvgUse::bounds(QPainter *p, QSvgExtraStates &states) const |
597 { |
|
598 if (m_link && m_bounds.isEmpty()) { |
|
599 m_bounds = m_link->bounds(); |
|
600 m_bounds = QRectF(m_bounds.x()+m_start.x(), |
|
601 m_bounds.y()+m_start.y(), |
|
602 m_bounds.width(), |
|
603 m_bounds.height()); |
|
604 |
|
605 return m_bounds; |
|
606 } |
|
607 return m_bounds; |
|
608 } |
|
609 |
|
610 QRectF QSvgUse::transformedBounds(const QTransform &transform) const |
|
611 { |
560 { |
612 QRectF bounds; |
561 QRectF bounds; |
613 QTransform t = transform; |
562 if (m_link) { |
614 |
563 p->translate(m_start); |
615 if (m_link) { |
564 bounds = m_link->transformedBounds(p, states); |
616 QSvgTransformStyle *transStyle = m_style.transform; |
565 p->translate(-m_start); |
617 if (transStyle) { |
|
618 t = transStyle->qtransform() * t; |
|
619 } |
|
620 t.translate(m_start.x(), m_start.y()); |
|
621 |
|
622 bounds = m_link->transformedBounds(t); |
|
623 |
|
624 return bounds; |
|
625 } |
566 } |
626 return bounds; |
567 return bounds; |
627 } |
568 } |
628 |
569 |
629 QRectF QSvgPolyline::bounds() const |
570 QRectF QSvgPolyline::bounds(QPainter *p, QSvgExtraStates &) const |
630 { |
571 { |
631 qreal sw = strokeWidth(); |
572 qreal sw = strokeWidth(p); |
632 if (qFuzzyIsNull(sw)) |
573 if (qFuzzyIsNull(sw)) { |
633 return m_poly.boundingRect(); |
574 return p->transform().map(m_poly).boundingRect(); |
634 else { |
575 } else { |
635 QPainterPath path; |
576 QPainterPath path; |
636 path.addPolygon(m_poly); |
577 path.addPolygon(m_poly); |
637 return boundsOnStroke(path, sw); |
578 return boundsOnStroke(p, path, sw); |
638 } |
579 } |
639 } |
580 } |
640 |
581 |
641 QRectF QSvgArc::bounds() const |
582 QRectF QSvgArc::bounds(QPainter *p, QSvgExtraStates &) const |
642 { |
583 { |
643 qreal sw = strokeWidth(); |
584 qreal sw = strokeWidth(p); |
644 if (qFuzzyIsNull(sw)) |
585 return qFuzzyIsNull(sw) ? p->transform().map(m_path).boundingRect() |
645 return m_cachedBounds; |
586 : boundsOnStroke(p, m_path, sw); |
646 else { |
587 } |
647 return boundsOnStroke(cubic, sw); |
588 |
648 } |
589 QRectF QSvgImage::bounds(QPainter *p, QSvgExtraStates &) const |
649 } |
590 { |
650 |
591 return p->transform().mapRect(m_bounds); |
651 QRectF QSvgImage::bounds() const |
592 } |
652 { |
593 |
653 return m_bounds; |
594 QRectF QSvgLine::bounds(QPainter *p, QSvgExtraStates &) const |
654 } |
595 { |
655 |
596 qreal sw = strokeWidth(p); |
656 QRectF QSvgLine::bounds() const |
|
657 { |
|
658 qreal sw = strokeWidth(); |
|
659 if (qFuzzyIsNull(sw)) { |
597 if (qFuzzyIsNull(sw)) { |
660 qreal minX = qMin(m_bounds.x1(), m_bounds.x2()); |
598 QPointF p1 = p->transform().map(m_line.p1()); |
661 qreal minY = qMin(m_bounds.y1(), m_bounds.y2()); |
599 QPointF p2 = p->transform().map(m_line.p2()); |
662 qreal maxX = qMax(m_bounds.x1(), m_bounds.x2()); |
600 qreal minX = qMin(p1.x(), p2.x()); |
663 qreal maxY = qMax(m_bounds.y1(), m_bounds.y2()); |
601 qreal minY = qMin(p1.y(), p2.y()); |
664 return QRectF(minX, minY, maxX-minX, maxY-minY); |
602 qreal maxX = qMax(p1.x(), p2.x()); |
|
603 qreal maxY = qMax(p1.y(), p2.y()); |
|
604 return QRectF(minX, minY, maxX - minX, maxY - minY); |
665 } else { |
605 } else { |
666 QPainterPath path; |
606 QPainterPath path; |
667 path.moveTo(m_bounds.x1(), m_bounds.y1()); |
607 path.moveTo(m_line.p1()); |
668 path.lineTo(m_bounds.x2(), m_bounds.y2()); |
608 path.lineTo(m_line.p2()); |
669 return boundsOnStroke(path, sw); |
609 return boundsOnStroke(p, path, sw); |
670 } |
610 } |
671 } |
611 } |
672 |
612 |
673 QT_END_NAMESPACE |
613 QT_END_NAMESPACE |
674 |
614 |