180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkPathMeasure_DEFINED 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPathMeasure_DEFINED 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPath.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTDArray.h" 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkPathMeasure : SkNoncopyable { 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPathMeasure(); 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Initialize the pathmeasure with the specified path. The path must remain valid 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for the lifetime of the measure object, or until setPath() is called with 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a different path (or null), since the measure object keeps a pointer to the 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru path object (does not copy its data). 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPathMeasure(const SkPath& path, bool forceClosed); 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ~SkPathMeasure(); 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Reset the pathmeasure with the specified path. The path must remain valid 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for the lifetime of the measure object, or until setPath() is called with 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a different path (or null), since the measure object keeps a pointer to the 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru path object (does not copy its data). 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void setPath(const SkPath*, bool forceClosed); 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Return the total length of the current contour, or 0 if no path 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru is associated (e.g. resetPath(null)) 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar getLength(); 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Pins distance to 0 <= distance <= getLength(), and then computes 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru the corresponding position and tangent. 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Returns false if there is no path, or a zero-length path was specified, in which case 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru position and tangent are unchanged. 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool SK_WARN_UNUSED_RESULT getPosTan(SkScalar distance, SkPoint* position, 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkVector* tangent); 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum MatrixFlags { 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kGetPosition_MatrixFlag = 0x01, 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kGetTangent_MatrixFlag = 0x02, 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kGetPosAndTan_MatrixFlag = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Pins distance to 0 <= distance <= getLength(), and then computes 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru the corresponding matrix (by calling getPosTan). 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Returns false if there is no path, or a zero-length path was specified, in which case 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru matrix is unchanged. 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool SK_WARN_UNUSED_RESULT getMatrix(SkScalar distance, SkMatrix* matrix, 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru MatrixFlags flags = kGetPosAndTan_MatrixFlag); 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Given a start and stop distance, return in dst the intervening segment(s). 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru If the segment is zero-length, return false, else return true. 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru startD and stopD are pinned to legal values (0..getLength()). If startD <= stopD 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru then return false (and leave dst untouched). 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Begin the segment with a moveTo if startWithMoveTo is true 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo); 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Return true if the current contour is closed() 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool isClosed(); 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Move to the next contour in the path. Return true if one exists, or false if 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru we're done with the path. 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool nextContour(); 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void dump(); 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPath::Iter fIter; 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPath* fPath; 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar fLength; // relative to the current contour 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fFirstPtIndex; // relative to the current contour 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fIsClosed; // relative to the current contour 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fForceClosed; 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct Segment { 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar fDistance; // total distance up to this point 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned fPtIndex : 15; // index into the fPts array 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned fTValue : 15; 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned fType : 2; 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar getScalarT() const; 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTDArray<Segment> fSegments; 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTDArray<SkPoint> fPts; // Points used to define the segments 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const Segment* NextSegment(const Segment*); 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void buildSegments(); 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance, 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int mint, int maxt, int ptIndex); 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance, 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int mint, int maxt, int ptIndex); 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Segment* distanceToSegment(SkScalar distance, SkScalar* t); 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 112