src/svg/qsvggraphics.cpp
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
equal deleted inserted replaced
27:93b982ccede2 31:5daf16870df6
    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 {
   320 {
   283 {
   321     m_size = size;
   284     m_size = size;
   322     m_type = TEXTAREA;
   285     m_type = TEXTAREA;
   323 }
   286 }
   324 
   287 
   325 //QRectF QSvgText::bounds() const {}
   288 //QRectF QSvgText::bounds(QPainter *p, QSvgExtraStates &) const {}
   326 
   289 
   327 void QSvgText::draw(QPainter *p, QSvgExtraStates &states)
   290 void QSvgText::draw(QPainter *p, QSvgExtraStates &states)
   328 {
   291 {
   329     applyStyle(p, states);
   292     applyStyle(p, states);
   330     qreal oldOpacity = p->opacity();
   293     qreal oldOpacity = p->opacity();
   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