Changeset 62383 in webkit


Ignore:
Timestamp:
Jul 2, 2010 8:15:43 AM (14 years ago)
Author:
vestbo@webkit.org
Message:

[Qt] Canvas arcTo() should draw straight line to p1 if p0, p1 and p2 are collinear

Reviewed by Simon Hausmann.

The implementation of PathQt's addArcTo() was not float-safe and also had
a case where it drew an 'infinite' line, which is not part of the spec.

http://www.whatwg.org/specs/web-apps/current-work/#dom-context-2d-arcto

We now use qFuzzyCompare() in both cases. The method isPointOnPathBorder()
also had the same problem, and was refactored a bit in the process of fixing
the bug.

Initial patch by Andreas Kling.

https://bugs.webkit.org/show_bug.cgi?id=41412

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r62381 r62383  
     12010-07-02  Tor Arne Vestbø  <tor.arne.vestbo@nokia.com>
     2
     3        Reviewed by Simon Hausmann.
     4
     5        [Qt] Canvas arcTo() should draw straight line to p1 if p0, p1 and p2 are collinear
     6
     7        The implementation of PathQt's addArcTo() was not float-safe and also had
     8        a case where it drew an 'infinite' line, which is not part of the spec.
     9
     10        http://www.whatwg.org/specs/web-apps/current-work/#dom-context-2d-arcto
     11
     12        We now use qFuzzyCompare() in both cases. The method isPointOnPathBorder()
     13        also had the same problem, and was refactored a bit in the process of fixing
     14        the bug.
     15
     16        Initial patch by Andreas Kling.
     17
     18        https://bugs.webkit.org/show_bug.cgi?id=41412
     19
     20        * platform/qt/Skipped:
     21
    1222010-07-02  Yury Semikhatsky  <yurys@chromium.org>
    223
  • trunk/LayoutTests/platform/qt/Skipped

    r62350 r62383  
    52675267canvas/philip/tests/2d.missingargs.html
    52685268canvas/philip/tests/2d.path.arc.twopie.3.html
    5269 canvas/philip/tests/2d.path.arcTo.collinear.2.html
    5270 canvas/philip/tests/2d.path.arcTo.collinear.3.html
    52715269canvas/philip/tests/2d.path.quadraticCurveTo.scaled.html
    52725270canvas/philip/tests/2d.path.quadraticCurveTo.shape.html
  • trunk/WebCore/ChangeLog

    r62380 r62383  
     12010-07-02  Tor Arne Vestbø  <tor.arne.vestbo@nokia.com>
     2
     3        Reviewed by Simon Hausmann.
     4
     5        [Qt] Canvas arcTo() should draw straight line to p1 if p0, p1 and p2 are collinear
     6
     7        The implementation of PathQt's addArcTo() was not float-safe and also had
     8        a case where it drew an 'infinite' line, which is not part of the spec.
     9
     10        http://www.whatwg.org/specs/web-apps/current-work/#dom-context-2d-arcto
     11
     12        We now use qFuzzyCompare() in both cases. The method isPointOnPathBorder()
     13        also had the same problem, and was refactored a bit in the process of fixing
     14        the bug.
     15
     16        Initial patch by Andreas Kling.
     17
     18        https://bugs.webkit.org/show_bug.cgi?id=41412
     19
     20        * platform/graphics/qt/PathQt.cpp:
     21
    1222010-07-02  Yury Semikhatsky  <yurys@chromium.org>
    223
  • trunk/WebCore/platform/graphics/qt/PathQt.cpp

    r60933 r62383  
    7070}
    7171
     72static inline bool areCollinear(const QPointF& a, const QPointF& b, const QPointF& c)
     73{
     74    // Solved from comparing the slopes of a to b and b to c: (ay-by)/(ax-bx) == (cy-by)/(cx-bx)
     75    return qFuzzyCompare((c.y() - b.y()) * (a.x() - b.x()), (a.y() - b.y()) * (c.x() - b.x()));
     76}
     77
     78static inline bool withinRange(qreal p, qreal a, qreal b)
     79{
     80    return (p >= a && p <= b) || (p >= b && p <= a);
     81}
     82
    7283// Check whether a point is on the border
    73 bool isPointOnPathBorder(const QPolygonF& border, const QPointF& p)
     84static bool isPointOnPathBorder(const QPolygonF& border, const QPointF& p)
    7485{
    7586    // null border doesn't contain points
     
    8293    for (int i = 1; i < border.size(); ++i) {
    8394        p2 = border.at(i);
    84         //  (x1<=x<=x2||x1=>x>=x2) && (y1<=y<=y2||y1=>y>=y2)  && (y2-y1)(x-x1) == (y-y1)(x2-x1)
    85         //  In which, (y2-y1)(x-x1) == (y-y1)(x2-x1) is from (y2-y1)/(x2-x1) == (y-y1)/(x-x1)
    86         //  it want to check the slope between p1 and p2 is same with slope between p and p1,
    87         //  if so then the three points lie on the same line.
    88         //  In which, (x1<=x<=x2||x1=>x>=x2) && (y1<=y<=y2||y1=>y>=y2) want to make sure p is
    89         //  between p1 and p2, not outside.
    90         if (((p.x() <= p1.x() && p.x() >= p2.x()) || (p.x() >= p1.x() && p.x() <= p2.x()))
    91             && ((p.y() <= p1.y() && p.y() >= p2.y()) || (p.y() >= p1.y() && p.y() <= p2.y()))
    92             && (p2.y() - p1.y()) * (p.x() - p1.x()) == (p.y() - p1.y()) * (p2.x() - p1.x())) {
     95        if (areCollinear(p, p1, p2)
     96                // Once we know that the points are collinear we
     97                // only need to check one of the coordinates
     98                && (qAbs(p2.x() - p1.x()) > qAbs(p2.y() - p1.y()) ?
     99                        withinRange(p.x(), p1.x(), p2.x()) :
     100                        withinRange(p.y(), p1.y(), p2.y()))) {
    93101            return true;
    94102        }
     
    213221
    214222    double cos_phi = (p1p0.x() * p1p2.x() + p1p0.y() * p1p2.y()) / (p1p0_length * p1p2_length);
    215     // all points on a line logic
    216     if (cos_phi == -1) {
     223
     224    // The points p0, p1, and p2 are on the same straight line (HTML5, 4.8.11.1.8)
     225    // We could have used areCollinear() here, but since we're reusing
     226    // the variables computed above later on we keep this logic.
     227    if (qFuzzyCompare(qAbs(cos_phi), 1.0)) {
    217228        m_path.lineTo(p1);
    218         return;
    219     }
    220     if (cos_phi == 1) {
    221         // add infinite far away point
    222         unsigned int max_length = 65535;
    223         double factor_max = max_length / p1p0_length;
    224         FloatPoint ep((p0.x() + factor_max * p1p0.x()), (p0.y() + factor_max * p1p0.y()));
    225         m_path.lineTo(ep);
    226229        return;
    227230    }
Note: See TracChangeset for help on using the changeset viewer.