LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkQuadClipper.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 46 0 0.0 %
Date: 2012-06-02 Functions: 5 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2009 The Android Open Source Project
       4                 :  *
       5                 :  * Use of this source code is governed by a BSD-style license that can be
       6                 :  * found in the LICENSE file.
       7                 :  */
       8                 : 
       9                 : 
      10                 : #include "SkQuadClipper.h"
      11                 : #include "SkGeometry.h"
      12                 : 
      13                 : static inline void clamp_le(SkScalar& value, SkScalar max) {
      14                 :     if (value > max) {
      15                 :         value = max;
      16                 :     }
      17                 : }
      18                 : 
      19                 : static inline void clamp_ge(SkScalar& value, SkScalar min) {
      20                 :     if (value < min) {
      21                 :         value = min;
      22                 :     }
      23                 : }
      24                 : 
      25               0 : SkQuadClipper::SkQuadClipper() {}
      26                 : 
      27               0 : void SkQuadClipper::setClip(const SkIRect& clip) {
      28                 :     // conver to scalars, since that's where we'll see the points
      29               0 :     fClip.set(clip);
      30               0 : }
      31                 : 
      32                 : ///////////////////////////////////////////////////////////////////////////////
      33                 : 
      34               0 : static bool chopMonoQuadAt(SkScalar c0, SkScalar c1, SkScalar c2,
      35                 :                            SkScalar target, SkScalar* t) {
      36                 :     /* Solve F(t) = y where F(t) := [0](1-t)^2 + 2[1]t(1-t) + [2]t^2
      37                 :      *  We solve for t, using quadratic equation, hence we have to rearrange
      38                 :      * our cooefficents to look like At^2 + Bt + C
      39                 :      */
      40               0 :     SkScalar A = c0 - c1 - c1 + c2;
      41               0 :     SkScalar B = 2*(c1 - c0);
      42               0 :     SkScalar C = c0 - target;
      43                 :     
      44                 :     SkScalar roots[2];  // we only expect one, but make room for 2 for safety
      45               0 :     int count = SkFindUnitQuadRoots(A, B, C, roots);
      46               0 :     if (count) {
      47               0 :         *t = roots[0];
      48               0 :         return true;
      49                 :     }
      50               0 :     return false;
      51                 : }
      52                 : 
      53               0 : static bool chopMonoQuadAtY(SkPoint pts[3], SkScalar y, SkScalar* t) {
      54               0 :     return chopMonoQuadAt(pts[0].fY, pts[1].fY, pts[2].fY, y, t);
      55                 : }
      56                 : 
      57                 : ///////////////////////////////////////////////////////////////////////////////
      58                 : 
      59                 : /*  If we somehow returned the fact that we had to flip the pts in Y, we could
      60                 :  communicate that to setQuadratic, and then avoid having to flip it back
      61                 :  here (only to have setQuadratic do the flip again)
      62                 :  */
      63               0 : bool SkQuadClipper::clipQuad(const SkPoint srcPts[3], SkPoint dst[3]) {
      64                 :     bool reverse;
      65                 :     
      66                 :     // we need the data to be monotonically increasing in Y
      67               0 :     if (srcPts[0].fY > srcPts[2].fY) {
      68               0 :         dst[0] = srcPts[2];
      69               0 :         dst[1] = srcPts[1];
      70               0 :         dst[2] = srcPts[0];
      71               0 :         reverse = true;
      72                 :     } else {
      73               0 :         memcpy(dst, srcPts, 3 * sizeof(SkPoint));
      74               0 :         reverse = false;
      75                 :     }
      76                 :     
      77                 :     // are we completely above or below
      78               0 :     const SkScalar ctop = fClip.fTop;
      79               0 :     const SkScalar cbot = fClip.fBottom;
      80               0 :     if (dst[2].fY <= ctop || dst[0].fY >= cbot) {
      81               0 :         return false;
      82                 :     }
      83                 :     
      84                 :     SkScalar t;
      85                 :     SkPoint tmp[5]; // for SkChopQuadAt
      86                 :     
      87                 :     // are we partially above
      88               0 :     if (dst[0].fY < ctop) {
      89               0 :         if (chopMonoQuadAtY(dst, ctop, &t)) {
      90                 :             // take the 2nd chopped quad
      91               0 :             SkChopQuadAt(dst, tmp, t);
      92               0 :             dst[0] = tmp[2];
      93               0 :             dst[1] = tmp[3];
      94                 :         } else {
      95                 :             // if chopMonoQuadAtY failed, then we may have hit inexact numerics
      96                 :             // so we just clamp against the top
      97               0 :             for (int i = 0; i < 3; i++) {
      98               0 :                 if (dst[i].fY < ctop) {
      99               0 :                     dst[i].fY = ctop;
     100                 :                 }
     101                 :             }
     102                 :         }
     103                 :     }
     104                 :     
     105                 :     // are we partially below
     106               0 :     if (dst[2].fY > cbot) {
     107               0 :         if (chopMonoQuadAtY(dst, cbot, &t)) {
     108               0 :             SkChopQuadAt(dst, tmp, t);
     109               0 :             dst[1] = tmp[1];
     110               0 :             dst[2] = tmp[2];
     111                 :         } else {
     112                 :             // if chopMonoQuadAtY failed, then we may have hit inexact numerics
     113                 :             // so we just clamp against the bottom
     114               0 :             for (int i = 0; i < 3; i++) {
     115               0 :                 if (dst[i].fY > cbot) {
     116               0 :                     dst[i].fY = cbot;
     117                 :                 }
     118                 :             }
     119                 :         }
     120                 :     }
     121                 :     
     122               0 :     if (reverse) {
     123               0 :         SkTSwap<SkPoint>(dst[0], dst[2]);
     124                 :     }
     125               0 :     return true;
     126                 : }
     127                 : 

Generated by: LCOV version 1.7