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 SkPathMeasure_DEFINED
      9 #define SkPathMeasure_DEFINED
     10 
     11 #include "SkPath.h"
     12 #include "SkTDArray.h"
     13 
     14 class SK_API SkPathMeasure : SkNoncopyable {
     15 public:
     16     SkPathMeasure();
     17     /** Initialize the pathmeasure with the specified path. The path must remain valid
     18         for the lifetime of the measure object, or until setPath() is called with
     19         a different path (or null), since the measure object keeps a pointer to the
     20         path object (does not copy its data).
     21     */
     22     SkPathMeasure(const SkPath& path, bool forceClosed);
     23     ~SkPathMeasure();
     24 
     25     /** Reset the pathmeasure with the specified path. The path must remain valid
     26         for the lifetime of the measure object, or until setPath() is called with
     27         a different path (or null), since the measure object keeps a pointer to the
     28         path object (does not copy its data).
     29     */
     30     void setPath(const SkPath*, bool forceClosed);
     31 
     32     /** Return the total length of the current contour, or 0 if no path
     33         is associated (e.g. resetPath(null))
     34     */
     35     SkScalar getLength();
     36 
     37     /** Pins distance to 0 <= distance <= getLength(), and then computes
     38         the corresponding position and tangent.
     39         Returns false if there is no path, or a zero-length path was specified, in which case
     40         position and tangent are unchanged.
     41     */
     42     bool SK_WARN_UNUSED_RESULT getPosTan(SkScalar distance, SkPoint* position,
     43                                          SkVector* tangent);
     44 
     45     enum MatrixFlags {
     46         kGetPosition_MatrixFlag     = 0x01,
     47         kGetTangent_MatrixFlag      = 0x02,
     48         kGetPosAndTan_MatrixFlag    = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
     49     };
     50 
     51     /** Pins distance to 0 <= distance <= getLength(), and then computes
     52         the corresponding matrix (by calling getPosTan).
     53         Returns false if there is no path, or a zero-length path was specified, in which case
     54         matrix is unchanged.
     55     */
     56     bool SK_WARN_UNUSED_RESULT getMatrix(SkScalar distance, SkMatrix* matrix,
     57                                   MatrixFlags flags = kGetPosAndTan_MatrixFlag);
     58 
     59     /** Given a start and stop distance, return in dst the intervening segment(s).
     60         If the segment is zero-length, return false, else return true.
     61         startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD
     62         then return false (and leave dst untouched).
     63         Begin the segment with a moveTo if startWithMoveTo is true
     64     */
     65     bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo);
     66 
     67     /** Return true if the current contour is closed()
     68     */
     69     bool isClosed();
     70 
     71     /** Move to the next contour in the path. Return true if one exists, or false if
     72         we're done with the path.
     73     */
     74     bool nextContour();
     75 
     76 #ifdef SK_DEBUG
     77     void    dump();
     78 #endif
     79 
     80 private:
     81     SkPath::Iter    fIter;
     82     const SkPath*   fPath;
     83     SkScalar        fLength;            // relative to the current contour
     84     int             fFirstPtIndex;      // relative to the current contour
     85     bool            fIsClosed;          // relative to the current contour
     86     bool            fForceClosed;
     87 
     88     struct Segment {
     89         SkScalar    fDistance;  // total distance up to this point
     90         unsigned    fPtIndex : 15; // index into the fPts array
     91         unsigned    fTValue : 15;
     92         unsigned    fType : 2;
     93 
     94         SkScalar getScalarT() const;
     95     };
     96     SkTDArray<Segment>  fSegments;
     97     SkTDArray<SkPoint>  fPts; // Points used to define the segments
     98 
     99     static const Segment* NextSegment(const Segment*);
    100 
    101     void     buildSegments();
    102     SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance,
    103                                 int mint, int maxt, int ptIndex);
    104     SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance,
    105                                 int mint, int maxt, int ptIndex);
    106     const Segment* distanceToSegment(SkScalar distance, SkScalar* t);
    107 };
    108 
    109 #endif
    110