• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/lib/ui/painting/path_measure.h"
6 
7 #define _USE_MATH_DEFINES
8 #include <math.h>
9 
10 #include "flutter/lib/ui/painting/matrix.h"
11 
12 using tonic::ToDart;
13 
14 namespace flutter {
15 
16 typedef CanvasPathMeasure PathMeasure;
17 
PathMeasure_constructor(Dart_NativeArguments args)18 static void PathMeasure_constructor(Dart_NativeArguments args) {
19   DartCallConstructor(&CanvasPathMeasure::Create, args);
20 }
21 
22 IMPLEMENT_WRAPPERTYPEINFO(ui, PathMeasure);
23 
24 #define FOR_EACH_BINDING(V)  \
25   V(PathMeasure, setPath)    \
26   V(PathMeasure, getLength)  \
27   V(PathMeasure, getPosTan)  \
28   V(PathMeasure, getSegment) \
29   V(PathMeasure, isClosed)   \
30   V(PathMeasure, nextContour)
31 
FOR_EACH_BINDING(DART_NATIVE_CALLBACK)32 FOR_EACH_BINDING(DART_NATIVE_CALLBACK)
33 
34 void CanvasPathMeasure::RegisterNatives(tonic::DartLibraryNatives* natives) {
35   natives->Register(
36       {{"PathMeasure_constructor", PathMeasure_constructor, 3, true},
37        FOR_EACH_BINDING(DART_REGISTER_NATIVE)});
38 }
39 
Create(const CanvasPath * path,bool forceClosed)40 fml::RefPtr<CanvasPathMeasure> CanvasPathMeasure::Create(const CanvasPath* path,
41                                                          bool forceClosed) {
42   fml::RefPtr<CanvasPathMeasure> pathMeasure =
43       fml::MakeRefCounted<CanvasPathMeasure>();
44   if (path) {
45     const SkPath skPath = path->path();
46     SkScalar resScale = 1;
47     pathMeasure->path_measure_ =
48         std::make_unique<SkContourMeasureIter>(skPath, forceClosed, resScale);
49   } else {
50     pathMeasure->path_measure_ = std::make_unique<SkContourMeasureIter>();
51   }
52   return pathMeasure;
53 }
54 
CanvasPathMeasure()55 CanvasPathMeasure::CanvasPathMeasure() {}
56 
~CanvasPathMeasure()57 CanvasPathMeasure::~CanvasPathMeasure() {}
58 
setPath(const CanvasPath * path,bool isClosed)59 void CanvasPathMeasure::setPath(const CanvasPath* path, bool isClosed) {
60   const SkPath& skPath = path->path();
61   path_measure_->reset(skPath, isClosed);
62 }
63 
getLength(int contourIndex)64 float CanvasPathMeasure::getLength(int contourIndex) {
65   if (static_cast<std::vector<sk_sp<SkContourMeasure>>::size_type>(
66           contourIndex) < measures_.size()) {
67     return measures_[contourIndex]->length();
68   }
69   return -1;
70 }
71 
getPosTan(int contourIndex,float distance)72 tonic::Float32List CanvasPathMeasure::getPosTan(int contourIndex,
73                                                 float distance) {
74   tonic::Float32List posTan(Dart_NewTypedData(Dart_TypedData_kFloat32, 5));
75   posTan[0] = 0;  // dart code will check for this for failure
76   if (static_cast<std::vector<sk_sp<SkContourMeasure>>::size_type>(
77           contourIndex) >= measures_.size()) {
78     return posTan;
79   }
80 
81   SkPoint pos;
82   SkVector tan;
83   bool success = measures_[contourIndex]->getPosTan(distance, &pos, &tan);
84 
85   if (success) {
86     posTan[0] = 1;  // dart code will check for this for success
87     posTan[1] = pos.x();
88     posTan[2] = pos.y();
89     posTan[3] = tan.x();
90     posTan[4] = tan.y();
91   }
92 
93   return posTan;
94 }
95 
getSegment(int contourIndex,float startD,float stopD,bool startWithMoveTo)96 fml::RefPtr<CanvasPath> CanvasPathMeasure::getSegment(int contourIndex,
97                                                       float startD,
98                                                       float stopD,
99                                                       bool startWithMoveTo) {
100   if (static_cast<std::vector<sk_sp<SkContourMeasure>>::size_type>(
101           contourIndex) >= measures_.size()) {
102     return CanvasPath::Create();
103   }
104   SkPath dst;
105   bool success =
106       measures_[contourIndex]->getSegment(startD, stopD, &dst, startWithMoveTo);
107   if (!success) {
108     return CanvasPath::Create();
109   } else {
110     return CanvasPath::CreateFrom(dst);
111   }
112 }
113 
isClosed(int contourIndex)114 bool CanvasPathMeasure::isClosed(int contourIndex) {
115   if (static_cast<std::vector<sk_sp<SkContourMeasure>>::size_type>(
116           contourIndex) < measures_.size()) {
117     return measures_[contourIndex]->isClosed();
118   }
119   return false;
120 }
121 
nextContour()122 bool CanvasPathMeasure::nextContour() {
123   auto measure = path_measure_->next();
124   if (measure) {
125     measures_.push_back(std::move(measure));
126     return true;
127   }
128   return false;
129 }
130 
131 }  // namespace flutter
132