Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/2d/PathSkia.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "PathSkia.h"
8
#include <math.h>
9
#include "DrawTargetSkia.h"
10
#include "Logging.h"
11
#include "HelpersSkia.h"
12
#include "PathHelpers.h"
13
14
namespace mozilla {
15
namespace gfx {
16
17
PathBuilderSkia::PathBuilderSkia(const Matrix& aTransform, const SkPath& aPath, FillRule aFillRule)
18
  : mPath(aPath)
19
0
{
20
0
  SkMatrix matrix;
21
0
  GfxMatrixToSkiaMatrix(aTransform, matrix);
22
0
  mPath.transform(matrix);
23
0
  SetFillRule(aFillRule);
24
0
}
25
26
PathBuilderSkia::PathBuilderSkia(FillRule aFillRule)
27
0
{
28
0
  SetFillRule(aFillRule);
29
0
}
30
31
void
32
PathBuilderSkia::SetFillRule(FillRule aFillRule)
33
0
{
34
0
  mFillRule = aFillRule;
35
0
  if (mFillRule == FillRule::FILL_WINDING) {
36
0
    mPath.setFillType(SkPath::kWinding_FillType);
37
0
  } else {
38
0
    mPath.setFillType(SkPath::kEvenOdd_FillType);
39
0
  }
40
0
}
41
42
void
43
PathBuilderSkia::MoveTo(const Point &aPoint)
44
0
{
45
0
  mPath.moveTo(SkFloatToScalar(aPoint.x), SkFloatToScalar(aPoint.y));
46
0
}
47
48
void
49
PathBuilderSkia::LineTo(const Point &aPoint)
50
0
{
51
0
  if (!mPath.countPoints()) {
52
0
    MoveTo(aPoint);
53
0
  } else {
54
0
    mPath.lineTo(SkFloatToScalar(aPoint.x), SkFloatToScalar(aPoint.y));
55
0
  }
56
0
}
57
58
void
59
PathBuilderSkia::BezierTo(const Point &aCP1,
60
                          const Point &aCP2,
61
                          const Point &aCP3)
62
0
{
63
0
  if (!mPath.countPoints()) {
64
0
    MoveTo(aCP1);
65
0
  }
66
0
  mPath.cubicTo(SkFloatToScalar(aCP1.x), SkFloatToScalar(aCP1.y),
67
0
                SkFloatToScalar(aCP2.x), SkFloatToScalar(aCP2.y),
68
0
                SkFloatToScalar(aCP3.x), SkFloatToScalar(aCP3.y));
69
0
}
70
71
void
72
PathBuilderSkia::QuadraticBezierTo(const Point &aCP1,
73
                                   const Point &aCP2)
74
0
{
75
0
  if (!mPath.countPoints()) {
76
0
    MoveTo(aCP1);
77
0
  }
78
0
  mPath.quadTo(SkFloatToScalar(aCP1.x), SkFloatToScalar(aCP1.y),
79
0
               SkFloatToScalar(aCP2.x), SkFloatToScalar(aCP2.y));
80
0
}
81
82
void
83
PathBuilderSkia::Close()
84
0
{
85
0
  mPath.close();
86
0
}
87
88
void
89
PathBuilderSkia::Arc(const Point &aOrigin, float aRadius, float aStartAngle,
90
                     float aEndAngle, bool aAntiClockwise)
91
0
{
92
0
  ArcToBezier(this, aOrigin, Size(aRadius, aRadius), aStartAngle, aEndAngle, aAntiClockwise);
93
0
}
94
95
Point
96
PathBuilderSkia::CurrentPoint() const
97
0
{
98
0
  int pointCount = mPath.countPoints();
99
0
  if (!pointCount) {
100
0
    return Point(0, 0);
101
0
  }
102
0
  SkPoint point = mPath.getPoint(pointCount - 1);
103
0
  return Point(SkScalarToFloat(point.fX), SkScalarToFloat(point.fY));
104
0
}
105
106
already_AddRefed<Path>
107
PathBuilderSkia::Finish()
108
0
{
109
0
  return MakeAndAddRef<PathSkia>(mPath, mFillRule);
110
0
}
111
112
void
113
PathBuilderSkia::AppendPath(const SkPath &aPath)
114
0
{
115
0
  mPath.addPath(aPath);
116
0
}
117
118
already_AddRefed<PathBuilder>
119
PathSkia::CopyToBuilder(FillRule aFillRule) const
120
0
{
121
0
  return TransformedCopyToBuilder(Matrix(), aFillRule);
122
0
}
123
124
already_AddRefed<PathBuilder>
125
PathSkia::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) const
126
0
{
127
0
  return MakeAndAddRef<PathBuilderSkia>(aTransform, mPath, aFillRule);
128
0
}
129
130
static bool
131
SkPathContainsPoint(const SkPath& aPath, const Point& aPoint, const Matrix& aTransform)
132
0
{
133
0
  Matrix inverse = aTransform;
134
0
  if (!inverse.Invert()) {
135
0
    return false;
136
0
  }
137
0
138
0
  SkPoint point = PointToSkPoint(inverse.TransformPoint(aPoint));
139
0
  return aPath.contains(point.fX, point.fY);
140
0
}
141
142
bool
143
PathSkia::ContainsPoint(const Point &aPoint, const Matrix &aTransform) const
144
0
{
145
0
  if (!mPath.isFinite()) {
146
0
    return false;
147
0
  }
148
0
149
0
  return SkPathContainsPoint(mPath, aPoint, aTransform);
150
0
}
151
152
bool
153
PathSkia::StrokeContainsPoint(const StrokeOptions &aStrokeOptions,
154
                              const Point &aPoint,
155
                              const Matrix &aTransform) const
156
0
{
157
0
  if (!mPath.isFinite()) {
158
0
    return false;
159
0
  }
160
0
161
0
  SkPaint paint;
162
0
  if (!StrokeOptionsToPaint(paint, aStrokeOptions)) {
163
0
    return false;
164
0
  }
165
0
166
0
  SkPath strokePath;
167
0
  paint.getFillPath(mPath, &strokePath);
168
0
169
0
  return SkPathContainsPoint(strokePath, aPoint, aTransform);
170
0
}
171
172
Rect
173
PathSkia::GetBounds(const Matrix &aTransform) const
174
0
{
175
0
  if (!mPath.isFinite()) {
176
0
    return Rect();
177
0
  }
178
0
179
0
  Rect bounds = SkRectToRect(mPath.computeTightBounds());
180
0
  return aTransform.TransformBounds(bounds);
181
0
}
182
183
Rect
184
PathSkia::GetStrokedBounds(const StrokeOptions &aStrokeOptions,
185
                           const Matrix &aTransform) const
186
0
{
187
0
  if (!mPath.isFinite()) {
188
0
    return Rect();
189
0
  }
190
0
191
0
  SkPaint paint;
192
0
  if (!StrokeOptionsToPaint(paint, aStrokeOptions)) {
193
0
    return Rect();
194
0
  }
195
0
196
0
  SkPath result;
197
0
  paint.getFillPath(mPath, &result);
198
0
199
0
  Rect bounds = SkRectToRect(result.computeTightBounds());
200
0
  return aTransform.TransformBounds(bounds);
201
0
}
202
203
void
204
PathSkia::StreamToSink(PathSink *aSink) const
205
0
{
206
0
  SkPath::RawIter iter(mPath);
207
0
208
0
  SkPoint points[4];
209
0
  SkPath::Verb currentVerb;
210
0
  while ((currentVerb = iter.next(points)) != SkPath::kDone_Verb) {
211
0
    switch (currentVerb) {
212
0
    case SkPath::kMove_Verb:
213
0
      aSink->MoveTo(SkPointToPoint(points[0]));
214
0
      break;
215
0
    case SkPath::kLine_Verb:
216
0
      aSink->LineTo(SkPointToPoint(points[1]));
217
0
      break;
218
0
    case SkPath::kCubic_Verb:
219
0
      aSink->BezierTo(SkPointToPoint(points[1]),
220
0
                      SkPointToPoint(points[2]),
221
0
                      SkPointToPoint(points[3]));
222
0
      break;
223
0
    case SkPath::kQuad_Verb:
224
0
      aSink->QuadraticBezierTo(SkPointToPoint(points[1]),
225
0
                               SkPointToPoint(points[2]));
226
0
      break;
227
0
    case SkPath::kClose_Verb:
228
0
      aSink->Close();
229
0
      break;
230
0
    default:
231
0
      MOZ_ASSERT(false);
232
0
      // Unexpected verb found in path!
233
0
    }
234
0
  }
235
0
}
236
237
} // namespace gfx
238
} // namespace mozilla