11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkPathMeasure_DEFINED
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkPathMeasure_DEFINED
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPath.h"
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTDArray.h"
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkPathMeasure : SkNoncopyable {
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathMeasure();
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Initialize the pathmeasure with the specified path. The path must remain valid
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        for the lifetime of the measure object, or until setPath() is called with
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        a different path (or null), since the measure object keeps a pointer to the
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path object (does not copy its data).
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathMeasure(const SkPath& path, bool forceClosed);
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ~SkPathMeasure();
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Reset the pathmeasure with the specified path. The path must remain valid
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        for the lifetime of the measure object, or until setPath() is called with
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        a different path (or null), since the measure object keeps a pointer to the
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path object (does not copy its data).
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void    setPath(const SkPath*, bool forceClosed);
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return the total length of the current contour, or 0 if no path
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        is associated (e.g. resetPath(null))
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar getLength();
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Pins distance to 0 <= distance <= getLength(), and then computes
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        the corresponding position and tangent.
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Returns false if there is no path, or a zero-length path was specified, in which case
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        position and tangent are unchanged.
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool getPosTan(SkScalar distance, SkPoint* position, SkVector* tangent);
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    enum MatrixFlags {
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kGetPosition_MatrixFlag     = 0x01,
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kGetTangent_MatrixFlag      = 0x02,
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kGetPosAndTan_MatrixFlag    = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Pins distance to 0 <= distance <= getLength(), and then computes
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        the corresponding matrix (by calling getPosTan).
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Returns false if there is no path, or a zero-length path was specified, in which case
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        matrix is unchanged.
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool getMatrix(SkScalar distance, SkMatrix* matrix, MatrixFlags flags = kGetPosAndTan_MatrixFlag);
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Given a start and stop distance, return in dst the intervening segment(s).
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        If the segment is zero-length, return false, else return true.
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        then return false (and leave dst untouched).
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Begin the segment with a moveTo if startWithMoveTo is true
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo);
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Return true if the current contour is closed()
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool isClosed();
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    /** Move to the next contour in the path. Return true if one exists, or false if
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        we're done with the path.
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    */
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool nextContour();
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void    dump();
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPath::Iter    fIter;
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkPath*   fPath;
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        fLength;            // relative to the current contour
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int             fFirstPtIndex;      // relative to the current contour
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool            fIsClosed;          // relative to the current contour
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool            fForceClosed;
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    struct Segment {
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar    fDistance;  // total distance up to this point
884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        unsigned    fPtIndex : 15; // index into the fPts array
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned    fTValue : 15;
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        unsigned    fType : 2;
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar getScalarT() const;
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTDArray<Segment>  fSegments;
954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkTDArray<SkPoint>  fPts; // Points used to define the segments
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static const Segment* NextSegment(const Segment*);
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void     buildSegments();
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance,
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                int mint, int maxt, int ptIndex);
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance,
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                int mint, int maxt, int ptIndex);
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const Segment* distanceToSegment(SkScalar distance, SkScalar* t);
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
108