Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2006 The Android Open Source Project
      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 SkPointPriv_DEFINED
      9 #define SkPointPriv_DEFINED
     10 
     11 #include "SkPoint.h"
     12 
     13 class SkPointPriv {
     14 public:
     15     enum Side {
     16         kLeft_Side  = -1,
     17         kOn_Side    =  0,
     18         kRight_Side =  1,
     19     };
     20 
     21     static bool AreFinite(const SkPoint array[], int count) {
     22         return SkScalarsAreFinite(&array[0].fX, count << 1);
     23     }
     24 
     25     static const SkScalar* AsScalars(const SkPoint& pt) { return &pt.fX; }
     26 
     27     static bool CanNormalize(SkScalar dx, SkScalar dy) {
     28         // Simple enough (and performance critical sometimes) so we inline it.
     29         return (dx*dx + dy*dy) > (SK_ScalarNearlyZero * SK_ScalarNearlyZero);
     30     }
     31 
     32     static SkScalar DistanceToLineBetweenSqd(const SkPoint& pt, const SkPoint& a,
     33                                              const SkPoint& b, Side* side = nullptr);
     34 
     35     static SkScalar DistanceToLineBetween(const SkPoint& pt, const SkPoint& a,
     36                                           const SkPoint& b, Side* side = nullptr) {
     37         return SkScalarSqrt(DistanceToLineBetweenSqd(pt, a, b, side));
     38     }
     39 
     40     static SkScalar DistanceToLineSegmentBetweenSqd(const SkPoint& pt, const SkPoint& a,
     41                                                    const SkPoint& b);
     42 
     43     static SkScalar DistanceToLineSegmentBetween(const SkPoint& pt, const SkPoint& a,
     44                                                  const SkPoint& b) {
     45         return SkScalarSqrt(DistanceToLineSegmentBetweenSqd(pt, a, b));
     46     }
     47 
     48     static SkScalar DistanceToSqd(const SkPoint& pt, const SkPoint& a) {
     49         SkScalar dx = pt.fX - a.fX;
     50         SkScalar dy = pt.fY - a.fY;
     51         return dx * dx + dy * dy;
     52     }
     53 
     54     static bool EqualsWithinTolerance(const SkPoint& p1, const SkPoint& p2) {
     55         return !CanNormalize(p1.fX - p2.fX, p1.fY - p2.fY);
     56     }
     57 
     58     static bool EqualsWithinTolerance(const SkPoint& pt, const SkPoint& p, SkScalar tol) {
     59         return SkScalarNearlyZero(pt.fX - p.fX, tol)
     60                && SkScalarNearlyZero(pt.fY - p.fY, tol);
     61     }
     62 
     63     static SkScalar LengthSqd(const SkPoint& pt) {
     64         return SkPoint::DotProduct(pt, pt);
     65     }
     66 
     67     static void Negate(SkIPoint& pt) {
     68         pt.fX = -pt.fX;
     69         pt.fY = -pt.fY;
     70     }
     71 
     72     static void RotateCCW(const SkPoint& src, SkPoint* dst) {
     73         // use a tmp in case src == dst
     74         SkScalar tmp = src.fX;
     75         dst->fX = src.fY;
     76         dst->fY = -tmp;
     77     }
     78 
     79     static void RotateCCW(SkPoint* pt) {
     80         RotateCCW(*pt, pt);
     81     }
     82 
     83     static void RotateCW(const SkPoint& src, SkPoint* dst) {
     84         // use a tmp in case src == dst
     85         SkScalar tmp = src.fX;
     86         dst->fX = -src.fY;
     87         dst->fY = tmp;
     88     }
     89 
     90     static void RotateCW(SkPoint* pt) {
     91         RotateCW(*pt, pt);
     92     }
     93 
     94     static bool SetLengthFast(SkPoint* pt, float length);
     95 
     96     static void SetOrthog(SkPoint* pt, const SkPoint& vec, Side side = kLeft_Side) {
     97         // vec could be this
     98         SkScalar tmp = vec.fX;
     99         if (kRight_Side == side) {
    100             pt->fX = -vec.fY;
    101             pt->fY = tmp;
    102         } else {
    103             SkASSERT(kLeft_Side == side);
    104             pt->fX = vec.fY;
    105             pt->fY = -tmp;
    106         }
    107     }
    108 
    109     // counter-clockwise fan
    110     static void SetRectFan(SkPoint v[], SkScalar l, SkScalar t, SkScalar r, SkScalar b,
    111             size_t stride) {
    112         SkASSERT(stride >= sizeof(SkPoint));
    113 
    114         ((SkPoint*)((intptr_t)v + 0 * stride))->set(l, t);
    115         ((SkPoint*)((intptr_t)v + 1 * stride))->set(l, b);
    116         ((SkPoint*)((intptr_t)v + 2 * stride))->set(r, b);
    117         ((SkPoint*)((intptr_t)v + 3 * stride))->set(r, t);
    118     }
    119 
    120     // tri strip with two counter-clockwise triangles
    121     static void SetRectTriStrip(SkPoint v[], SkScalar l, SkScalar t, SkScalar r, SkScalar b,
    122             size_t stride) {
    123         SkASSERT(stride >= sizeof(SkPoint));
    124 
    125         ((SkPoint*)((intptr_t)v + 0 * stride))->set(l, t);
    126         ((SkPoint*)((intptr_t)v + 1 * stride))->set(l, b);
    127         ((SkPoint*)((intptr_t)v + 2 * stride))->set(r, t);
    128         ((SkPoint*)((intptr_t)v + 3 * stride))->set(r, b);
    129     }
    130 
    131 };
    132 
    133 #endif
    134