1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2006 The Android Open Source Project
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SkPathMeasure_DEFINED
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define SkPathMeasure_DEFINED
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "../private/SkTDArray.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPath.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct SkConic;
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass SK_API SkPathMeasure : SkNoncopyable {
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPathMeasure();
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Initialize the pathmeasure with the specified path. The path must remain valid
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for the lifetime of the measure object, or until setPath() is called with
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        a different path (or null), since the measure object keeps a pointer to the
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path object (does not copy its data).
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        resScale controls the precision of the measure. values > 1 increase the
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        precision (and possible slow down the computation).
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    */
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPathMeasure(const SkPath& path, bool forceClosed, SkScalar resScale = 1);
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~SkPathMeasure();
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Reset the pathmeasure with the specified path. The path must remain valid
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        for the lifetime of the measure object, or until setPath() is called with
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        a different path (or null), since the measure object keeps a pointer to the
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        path object (does not copy its data).
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    */
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void setPath(const SkPath*, bool forceClosed);
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Return the total length of the current contour, or 0 if no path
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        is associated (e.g. resetPath(null))
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    */
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar getLength();
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Pins distance to 0 <= distance <= getLength(), and then computes
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        the corresponding position and tangent.
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Returns false if there is no path, or a zero-length path was specified, in which case
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        position and tangent are unchanged.
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    */
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool SK_WARN_UNUSED_RESULT getPosTan(SkScalar distance, SkPoint* position,
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                         SkVector* tangent);
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum MatrixFlags {
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kGetPosition_MatrixFlag     = 0x01,
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kGetTangent_MatrixFlag      = 0x02,
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kGetPosAndTan_MatrixFlag    = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Pins distance to 0 <= distance <= getLength(), and then computes
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        the corresponding matrix (by calling getPosTan).
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Returns false if there is no path, or a zero-length path was specified, in which case
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        matrix is unchanged.
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    */
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool SK_WARN_UNUSED_RESULT getMatrix(SkScalar distance, SkMatrix* matrix,
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                  MatrixFlags flags = kGetPosAndTan_MatrixFlag);
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Given a start and stop distance, return in dst the intervening segment(s).
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        If the segment is zero-length, return false, else return true.
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        startD and stopD are pinned to legal values (0..getLength()). If startD > stopD
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        then return false (and leave dst untouched).
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Begin the segment with a moveTo if startWithMoveTo is true
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    */
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo);
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Return true if the current contour is closed()
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    */
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool isClosed();
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    /** Move to the next contour in the path. Return true if one exists, or false if
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        we're done with the path.
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    */
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool nextContour();
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void    dump();
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkPath::Iter    fIter;
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const SkPath*   fPath;
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar        fTolerance;
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar        fLength;            // relative to the current contour
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int             fFirstPtIndex;      // relative to the current contour
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool            fIsClosed;          // relative to the current contour
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool            fForceClosed;
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    struct Segment {
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar    fDistance;  // total distance up to this point
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unsigned    fPtIndex; // index into the fPts array
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unsigned    fTValue : 30;
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        unsigned    fType : 2;  // actually the enum SkSegType
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                // See SkPathMeasurePriv.h
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkScalar getScalarT() const;
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTDArray<Segment>  fSegments;
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkTDArray<SkPoint>  fPts; // Points used to define the segments
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const Segment* NextSegment(const Segment*);
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void     buildSegments();
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance,
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                int mint, int maxt, int ptIndex);
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar compute_conic_segs(const SkConic&, SkScalar distance,
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                int mint, const SkPoint& minPt,
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                int maxt, const SkPoint& maxPt, int ptIndex);
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance,
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                int mint, int maxt, int ptIndex);
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const Segment* distanceToSegment(SkScalar distance, SkScalar* t);
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool quad_too_curvy(const SkPoint pts[3]);
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool conic_too_curvy(const SkPoint& firstPt, const SkPoint& midTPt,const SkPoint& lastPt);
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool cheap_dist_exceeds_limit(const SkPoint& pt, SkScalar x, SkScalar y);
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool cubic_too_curvy(const SkPoint pts[4]);
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
124