Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef SkPathMeasure_DEFINED
     18 #define SkPathMeasure_DEFINED
     19 
     20 #include "SkPath.h"
     21 #include "SkTDArray.h"
     22 
     23 class SkPathMeasure : SkNoncopyable {
     24 public:
     25     SkPathMeasure();
     26     /** Initialize the pathmeasure with the specified path. The path must remain valid
     27         for the lifetime of the measure object, or until setPath() is called with
     28         a different path (or null), since the measure object keeps a pointer to the
     29         path object (does not copy its data).
     30     */
     31     SkPathMeasure(const SkPath& path, bool forceClosed);
     32     ~SkPathMeasure();
     33 
     34     /** Reset the pathmeasure with the specified path. The path must remain valid
     35         for the lifetime of the measure object, or until setPath() is called with
     36         a different path (or null), since the measure object keeps a pointer to the
     37         path object (does not copy its data).
     38     */
     39     void    setPath(const SkPath*, bool forceClosed);
     40 
     41     /** Return the total length of the current contour, or 0 if no path
     42         is associated (e.g. resetPath(null))
     43     */
     44     SkScalar getLength();
     45 
     46     /** Pins distance to 0 <= distance <= getLength(), and then computes
     47         the corresponding position and tangent.
     48         Returns false if there is no path, or a zero-length path was specified, in which case
     49         position and tangent are unchanged.
     50     */
     51     bool getPosTan(SkScalar distance, SkPoint* position, SkVector* tangent);
     52 
     53     enum MatrixFlags {
     54         kGetPosition_MatrixFlag     = 0x01,
     55         kGetTangent_MatrixFlag      = 0x02,
     56         kGetPosAndTan_MatrixFlag    = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
     57     };
     58     /** Pins distance to 0 <= distance <= getLength(), and then computes
     59         the corresponding matrix (by calling getPosTan).
     60         Returns false if there is no path, or a zero-length path was specified, in which case
     61         matrix is unchanged.
     62     */
     63     bool getMatrix(SkScalar distance, SkMatrix* matrix, MatrixFlags flags = kGetPosAndTan_MatrixFlag);
     64     /** Given a start and stop distance, return in dst the intervening segment(s).
     65         If the segment is zero-length, return false, else return true.
     66         startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD
     67         then return false (and leave dst untouched).
     68         Begin the segment with a moveTo if startWithMoveTo is true
     69     */
     70     bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo);
     71 
     72     /** Return true if the current contour is closed()
     73     */
     74     bool isClosed();
     75 
     76     /** Move to the next contour in the path. Return true if one exists, or false if
     77         we're done with the path.
     78     */
     79     bool nextContour();
     80 
     81 #ifdef SK_DEBUG
     82     void    dump();
     83 #endif
     84 
     85 private:
     86     SkPath::Iter    fIter;
     87     const SkPath*   fPath;
     88     SkScalar        fLength;            // relative to the current contour
     89     int             fFirstPtIndex;      // relative to the current contour
     90     bool            fIsClosed;          // relative to the current contour
     91     bool            fForceClosed;
     92 
     93     struct Segment {
     94         SkScalar    fDistance;  // total distance up to this point
     95         unsigned    fPtIndex : 15;
     96         unsigned    fTValue : 15;
     97         unsigned    fType : 2;
     98 
     99         SkScalar getScalarT() const;
    100     };
    101     SkTDArray<Segment>  fSegments;
    102 
    103     static const Segment* NextSegment(const Segment*);
    104 
    105     void     buildSegments();
    106     SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance,
    107                                 int mint, int maxt, int ptIndex);
    108     SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance,
    109                                 int mint, int maxt, int ptIndex);
    110     const Segment* distanceToSegment(SkScalar distance, SkScalar* t);
    111 };
    112 
    113 #endif
    114 
    115