1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "DrawTargetSkia.h"
10 #include "HelpersSkia.h"
11 #include "PathHelpers.h"
16 PathBuilderSkia::PathBuilderSkia(const Matrix
& aTransform
, const SkPath
& aPath
, FillRule aFillRule
)
20 GfxMatrixToSkiaMatrix(aTransform
, matrix
);
21 mPath
.transform(matrix
);
22 SetFillRule(aFillRule
);
25 PathBuilderSkia::PathBuilderSkia(FillRule aFillRule
)
27 SetFillRule(aFillRule
);
31 PathBuilderSkia::SetFillRule(FillRule aFillRule
)
33 mFillRule
= aFillRule
;
34 if (mFillRule
== FillRule::FILL_WINDING
) {
35 mPath
.setFillType(SkPath::kWinding_FillType
);
37 mPath
.setFillType(SkPath::kEvenOdd_FillType
);
42 PathBuilderSkia::MoveTo(const Point
&aPoint
)
44 mPath
.moveTo(SkFloatToScalar(aPoint
.x
), SkFloatToScalar(aPoint
.y
));
48 PathBuilderSkia::LineTo(const Point
&aPoint
)
50 if (!mPath
.countPoints()) {
53 mPath
.lineTo(SkFloatToScalar(aPoint
.x
), SkFloatToScalar(aPoint
.y
));
58 PathBuilderSkia::BezierTo(const Point
&aCP1
,
62 if (!mPath
.countPoints()) {
65 mPath
.cubicTo(SkFloatToScalar(aCP1
.x
), SkFloatToScalar(aCP1
.y
),
66 SkFloatToScalar(aCP2
.x
), SkFloatToScalar(aCP2
.y
),
67 SkFloatToScalar(aCP3
.x
), SkFloatToScalar(aCP3
.y
));
71 PathBuilderSkia::QuadraticBezierTo(const Point
&aCP1
,
74 if (!mPath
.countPoints()) {
77 mPath
.quadTo(SkFloatToScalar(aCP1
.x
), SkFloatToScalar(aCP1
.y
),
78 SkFloatToScalar(aCP2
.x
), SkFloatToScalar(aCP2
.y
));
82 PathBuilderSkia::Close()
88 PathBuilderSkia::Arc(const Point
&aOrigin
, float aRadius
, float aStartAngle
,
89 float aEndAngle
, bool aAntiClockwise
)
91 ArcToBezier(this, aOrigin
, Size(aRadius
, aRadius
), aStartAngle
, aEndAngle
, aAntiClockwise
);
95 PathBuilderSkia::CurrentPoint() const
97 int pointCount
= mPath
.countPoints();
101 SkPoint point
= mPath
.getPoint(pointCount
- 1);
102 return Point(SkScalarToFloat(point
.fX
), SkScalarToFloat(point
.fY
));
106 PathBuilderSkia::Finish()
108 return new PathSkia(mPath
, mFillRule
);
112 PathBuilderSkia::AppendPath(const SkPath
&aPath
)
114 mPath
.addPath(aPath
);
117 TemporaryRef
<PathBuilder
>
118 PathSkia::CopyToBuilder(FillRule aFillRule
) const
120 return TransformedCopyToBuilder(Matrix(), aFillRule
);
123 TemporaryRef
<PathBuilder
>
124 PathSkia::TransformedCopyToBuilder(const Matrix
&aTransform
, FillRule aFillRule
) const
126 return new PathBuilderSkia(aTransform
, mPath
, aFillRule
);
130 PathSkia::ContainsPoint(const Point
&aPoint
, const Matrix
&aTransform
) const
132 Matrix inverse
= aTransform
;
134 Point transformed
= inverse
* aPoint
;
136 Rect bounds
= GetBounds(aTransform
);
138 if (aPoint
.x
< bounds
.x
|| aPoint
.y
< bounds
.y
||
139 aPoint
.x
> bounds
.XMost() || aPoint
.y
> bounds
.YMost()) {
144 pointRect
.setRect(int32_t(SkFloatToScalar(transformed
.x
- 1.f
)),
145 int32_t(SkFloatToScalar(transformed
.y
- 1.f
)),
146 int32_t(SkFloatToScalar(transformed
.x
+ 1.f
)),
147 int32_t(SkFloatToScalar(transformed
.y
+ 1.f
)));
151 return pathRegion
.setPath(mPath
, pointRect
);
155 PathSkia::StrokeContainsPoint(const StrokeOptions
&aStrokeOptions
,
157 const Matrix
&aTransform
) const
159 Matrix inverse
= aTransform
;
161 Point transformed
= inverse
* aPoint
;
164 StrokeOptionsToPaint(paint
, aStrokeOptions
);
167 paint
.getFillPath(mPath
, &strokePath
);
169 Rect bounds
= aTransform
.TransformBounds(SkRectToRect(strokePath
.getBounds()));
171 if (aPoint
.x
< bounds
.x
|| aPoint
.y
< bounds
.y
||
172 aPoint
.x
> bounds
.XMost() || aPoint
.y
> bounds
.YMost()) {
177 pointRect
.setRect(int32_t(SkFloatToScalar(transformed
.x
- 1.f
)),
178 int32_t(SkFloatToScalar(transformed
.y
- 1.f
)),
179 int32_t(SkFloatToScalar(transformed
.x
+ 1.f
)),
180 int32_t(SkFloatToScalar(transformed
.y
+ 1.f
)));
184 return pathRegion
.setPath(strokePath
, pointRect
);
188 PathSkia::GetBounds(const Matrix
&aTransform
) const
190 Rect bounds
= SkRectToRect(mPath
.getBounds());
191 return aTransform
.TransformBounds(bounds
);
195 PathSkia::GetStrokedBounds(const StrokeOptions
&aStrokeOptions
,
196 const Matrix
&aTransform
) const
199 StrokeOptionsToPaint(paint
, aStrokeOptions
);
202 paint
.getFillPath(mPath
, &result
);
204 Rect bounds
= SkRectToRect(result
.getBounds());
205 return aTransform
.TransformBounds(bounds
);
209 PathSkia::StreamToSink(PathSink
*aSink
) const
211 SkPath::RawIter
iter(mPath
);
214 SkPath::Verb currentVerb
;
215 while ((currentVerb
= iter
.next(points
)) != SkPath::kDone_Verb
) {
216 switch (currentVerb
) {
217 case SkPath::kMove_Verb
:
218 aSink
->MoveTo(SkPointToPoint(points
[0]));
220 case SkPath::kLine_Verb
:
221 aSink
->LineTo(SkPointToPoint(points
[1]));
223 case SkPath::kCubic_Verb
:
224 aSink
->BezierTo(SkPointToPoint(points
[1]),
225 SkPointToPoint(points
[2]),
226 SkPointToPoint(points
[3]));
228 case SkPath::kQuad_Verb
:
229 aSink
->QuadraticBezierTo(SkPointToPoint(points
[1]),
230 SkPointToPoint(points
[2]));
232 case SkPath::kClose_Verb
:
237 // Unexpected verb found in path!