LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/pathops - SkLineParameters.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 81 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2012 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #ifndef SkLineParameters_DEFINED
       9             : #define SkLineParameters_DEFINED
      10             : 
      11             : #include "SkPathOpsCubic.h"
      12             : #include "SkPathOpsLine.h"
      13             : #include "SkPathOpsQuad.h"
      14             : 
      15             : // Sources
      16             : // computer-aided design - volume 22 number 9 november 1990 pp 538 - 549
      17             : // online at http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf
      18             : 
      19             : // This turns a line segment into a parameterized line, of the form
      20             : // ax + by + c = 0
      21             : // When a^2 + b^2 == 1, the line is normalized.
      22             : // The distance to the line for (x, y) is d(x,y) = ax + by + c
      23             : //
      24             : // Note that the distances below are not necessarily normalized. To get the true
      25             : // distance, it's necessary to either call normalize() after xxxEndPoints(), or
      26             : // divide the result of xxxDistance() by sqrt(normalSquared())
      27             : 
      28             : class SkLineParameters {
      29             : public:
      30             : 
      31           0 :     bool cubicEndPoints(const SkDCubic& pts) {
      32           0 :         int endIndex = 1;
      33           0 :         cubicEndPoints(pts, 0, endIndex);
      34           0 :         if (dy() != 0) {
      35           0 :             return true;
      36             :         }
      37           0 :         if (dx() == 0) {
      38           0 :             cubicEndPoints(pts, 0, ++endIndex);
      39           0 :             SkASSERT(endIndex == 2);
      40           0 :             if (dy() != 0) {
      41           0 :                 return true;
      42             :             }
      43           0 :             if (dx() == 0) {
      44           0 :                 cubicEndPoints(pts, 0, ++endIndex);  // line
      45           0 :                 SkASSERT(endIndex == 3);
      46           0 :                 return false;
      47             :             }
      48             :         }
      49             :         // FIXME: after switching to round sort, remove bumping fA
      50           0 :         if (dx() < 0) { // only worry about y bias when breaking cw/ccw tie
      51           0 :             return true;
      52             :         }
      53             :         // if cubic tangent is on x axis, look at next control point to break tie
      54             :         // control point may be approximate, so it must move significantly to account for error
      55           0 :         if (NotAlmostEqualUlps(pts[0].fY, pts[++endIndex].fY)) {
      56           0 :             if (pts[0].fY > pts[endIndex].fY) {
      57           0 :                 fA = DBL_EPSILON; // push it from 0 to slightly negative (y() returns -a)
      58             :             }
      59           0 :             return true;
      60             :         }
      61           0 :         if (endIndex == 3) {
      62           0 :             return true;
      63             :         }
      64           0 :         SkASSERT(endIndex == 2);
      65           0 :         if (pts[0].fY > pts[3].fY) {
      66           0 :             fA = DBL_EPSILON; // push it from 0 to slightly negative (y() returns -a)
      67             :         }
      68           0 :         return true;
      69             :     }
      70             : 
      71           0 :     void cubicEndPoints(const SkDCubic& pts, int s, int e) {
      72           0 :         fA = pts[s].fY - pts[e].fY;
      73           0 :         fB = pts[e].fX - pts[s].fX;
      74           0 :         fC = pts[s].fX * pts[e].fY - pts[e].fX * pts[s].fY;
      75           0 :     }
      76             : 
      77           0 :     double cubicPart(const SkDCubic& part) {
      78           0 :         cubicEndPoints(part);
      79           0 :         if (part[0] == part[1] || ((const SkDLine& ) part[0]).nearRay(part[2])) {
      80           0 :             return pointDistance(part[3]);
      81             :         }
      82           0 :         return pointDistance(part[2]);
      83             :     }
      84             : 
      85           0 :     void lineEndPoints(const SkDLine& pts) {
      86           0 :         fA = pts[0].fY - pts[1].fY;
      87           0 :         fB = pts[1].fX - pts[0].fX;
      88           0 :         fC = pts[0].fX * pts[1].fY - pts[1].fX * pts[0].fY;
      89           0 :     }
      90             : 
      91           0 :     bool quadEndPoints(const SkDQuad& pts) {
      92           0 :         quadEndPoints(pts, 0, 1);
      93           0 :         if (dy() != 0) {
      94           0 :             return true;
      95             :         }
      96           0 :         if (dx() == 0) {
      97           0 :             quadEndPoints(pts, 0, 2);
      98           0 :             return false;
      99             :         }
     100           0 :         if (dx() < 0) { // only worry about y bias when breaking cw/ccw tie
     101           0 :             return true;
     102             :         }
     103             :         // FIXME: after switching to round sort, remove this
     104           0 :         if (pts[0].fY > pts[2].fY) {
     105           0 :             fA = DBL_EPSILON;
     106             :         }
     107           0 :         return true;
     108             :     }
     109             : 
     110           0 :     void quadEndPoints(const SkDQuad& pts, int s, int e) {
     111           0 :         fA = pts[s].fY - pts[e].fY;
     112           0 :         fB = pts[e].fX - pts[s].fX;
     113           0 :         fC = pts[s].fX * pts[e].fY - pts[e].fX * pts[s].fY;
     114           0 :     }
     115             : 
     116             :     double quadPart(const SkDQuad& part) {
     117             :         quadEndPoints(part);
     118             :         return pointDistance(part[2]);
     119             :     }
     120             : 
     121           0 :     double normalSquared() const {
     122           0 :         return fA * fA + fB * fB;
     123             :     }
     124             : 
     125           0 :     bool normalize() {
     126           0 :         double normal = sqrt(normalSquared());
     127           0 :         if (approximately_zero(normal)) {
     128           0 :             fA = fB = fC = 0;
     129           0 :             return false;
     130             :         }
     131           0 :         double reciprocal = 1 / normal;
     132           0 :         fA *= reciprocal;
     133           0 :         fB *= reciprocal;
     134           0 :         fC *= reciprocal;
     135           0 :         return true;
     136             :     }
     137             : 
     138             :     void cubicDistanceY(const SkDCubic& pts, SkDCubic& distance) const {
     139             :         double oneThird = 1 / 3.0;
     140             :         for (int index = 0; index < 4; ++index) {
     141             :             distance[index].fX = index * oneThird;
     142             :             distance[index].fY = fA * pts[index].fX + fB * pts[index].fY + fC;
     143             :         }
     144             :     }
     145             : 
     146             :     void quadDistanceY(const SkDQuad& pts, SkDQuad& distance) const {
     147             :         double oneHalf = 1 / 2.0;
     148             :         for (int index = 0; index < 3; ++index) {
     149             :             distance[index].fX = index * oneHalf;
     150             :             distance[index].fY = fA * pts[index].fX + fB * pts[index].fY + fC;
     151             :         }
     152             :     }
     153             : 
     154           0 :     double controlPtDistance(const SkDCubic& pts, int index) const {
     155           0 :         SkASSERT(index == 1 || index == 2);
     156           0 :         return fA * pts[index].fX + fB * pts[index].fY + fC;
     157             :     }
     158             : 
     159           0 :     double controlPtDistance(const SkDQuad& pts) const {
     160           0 :         return fA * pts[1].fX + fB * pts[1].fY + fC;
     161             :     }
     162             : 
     163           0 :     double pointDistance(const SkDPoint& pt) const {
     164           0 :         return fA * pt.fX + fB * pt.fY + fC;
     165             :     }
     166             : 
     167           0 :     double dx() const {
     168           0 :         return fB;
     169             :     }
     170             : 
     171           0 :     double dy() const {
     172           0 :         return -fA;
     173             :     }
     174             : 
     175             : private:
     176             :     double fA;
     177             :     double fB;
     178             :     double fC;
     179             : };
     180             : 
     181             : #endif

Generated by: LCOV version 1.13