Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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/. */
6 #include "PathSkia.h"
7 #include <math.h>
8 #include "DrawTargetSkia.h"
9 #include "Logging.h"
10 #include "HelpersSkia.h"
11 #include "PathHelpers.h"
13 namespace mozilla {
14 namespace gfx {
16 PathBuilderSkia::PathBuilderSkia(const Matrix& aTransform, const SkPath& aPath, FillRule aFillRule)
17 : mPath(aPath)
18 {
19 SkMatrix matrix;
20 GfxMatrixToSkiaMatrix(aTransform, matrix);
21 mPath.transform(matrix);
22 SetFillRule(aFillRule);
23 }
25 PathBuilderSkia::PathBuilderSkia(FillRule aFillRule)
26 {
27 SetFillRule(aFillRule);
28 }
30 void
31 PathBuilderSkia::SetFillRule(FillRule aFillRule)
32 {
33 mFillRule = aFillRule;
34 if (mFillRule == FillRule::FILL_WINDING) {
35 mPath.setFillType(SkPath::kWinding_FillType);
36 } else {
37 mPath.setFillType(SkPath::kEvenOdd_FillType);
38 }
39 }
41 void
42 PathBuilderSkia::MoveTo(const Point &aPoint)
43 {
44 mPath.moveTo(SkFloatToScalar(aPoint.x), SkFloatToScalar(aPoint.y));
45 }
47 void
48 PathBuilderSkia::LineTo(const Point &aPoint)
49 {
50 if (!mPath.countPoints()) {
51 MoveTo(aPoint);
52 } else {
53 mPath.lineTo(SkFloatToScalar(aPoint.x), SkFloatToScalar(aPoint.y));
54 }
55 }
57 void
58 PathBuilderSkia::BezierTo(const Point &aCP1,
59 const Point &aCP2,
60 const Point &aCP3)
61 {
62 if (!mPath.countPoints()) {
63 MoveTo(aCP1);
64 }
65 mPath.cubicTo(SkFloatToScalar(aCP1.x), SkFloatToScalar(aCP1.y),
66 SkFloatToScalar(aCP2.x), SkFloatToScalar(aCP2.y),
67 SkFloatToScalar(aCP3.x), SkFloatToScalar(aCP3.y));
68 }
70 void
71 PathBuilderSkia::QuadraticBezierTo(const Point &aCP1,
72 const Point &aCP2)
73 {
74 if (!mPath.countPoints()) {
75 MoveTo(aCP1);
76 }
77 mPath.quadTo(SkFloatToScalar(aCP1.x), SkFloatToScalar(aCP1.y),
78 SkFloatToScalar(aCP2.x), SkFloatToScalar(aCP2.y));
79 }
81 void
82 PathBuilderSkia::Close()
83 {
84 mPath.close();
85 }
87 void
88 PathBuilderSkia::Arc(const Point &aOrigin, float aRadius, float aStartAngle,
89 float aEndAngle, bool aAntiClockwise)
90 {
91 ArcToBezier(this, aOrigin, Size(aRadius, aRadius), aStartAngle, aEndAngle, aAntiClockwise);
92 }
94 Point
95 PathBuilderSkia::CurrentPoint() const
96 {
97 int pointCount = mPath.countPoints();
98 if (!pointCount) {
99 return Point(0, 0);
100 }
101 SkPoint point = mPath.getPoint(pointCount - 1);
102 return Point(SkScalarToFloat(point.fX), SkScalarToFloat(point.fY));
103 }
105 TemporaryRef<Path>
106 PathBuilderSkia::Finish()
107 {
108 RefPtr<PathSkia> path = new PathSkia(mPath, mFillRule);
109 return path;
110 }
112 void
113 PathBuilderSkia::AppendPath(const SkPath &aPath)
114 {
115 mPath.addPath(aPath);
116 }
118 TemporaryRef<PathBuilder>
119 PathSkia::CopyToBuilder(FillRule aFillRule) const
120 {
121 return TransformedCopyToBuilder(Matrix(), aFillRule);
122 }
124 TemporaryRef<PathBuilder>
125 PathSkia::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) const
126 {
127 RefPtr<PathBuilderSkia> builder = new PathBuilderSkia(aTransform, mPath, aFillRule);
128 return builder;
129 }
131 bool
132 PathSkia::ContainsPoint(const Point &aPoint, const Matrix &aTransform) const
133 {
134 Matrix inverse = aTransform;
135 inverse.Invert();
136 Point transformed = inverse * aPoint;
138 Rect bounds = GetBounds(aTransform);
140 if (aPoint.x < bounds.x || aPoint.y < bounds.y ||
141 aPoint.x > bounds.XMost() || aPoint.y > bounds.YMost()) {
142 return false;
143 }
145 SkRegion pointRect;
146 pointRect.setRect(int32_t(SkFloatToScalar(transformed.x - 1)),
147 int32_t(SkFloatToScalar(transformed.y - 1)),
148 int32_t(SkFloatToScalar(transformed.x + 1)),
149 int32_t(SkFloatToScalar(transformed.y + 1)));
151 SkRegion pathRegion;
153 return pathRegion.setPath(mPath, pointRect);
154 }
156 bool
157 PathSkia::StrokeContainsPoint(const StrokeOptions &aStrokeOptions,
158 const Point &aPoint,
159 const Matrix &aTransform) const
160 {
161 Matrix inverse = aTransform;
162 inverse.Invert();
163 Point transformed = inverse * aPoint;
165 SkPaint paint;
166 StrokeOptionsToPaint(paint, aStrokeOptions);
168 SkPath strokePath;
169 paint.getFillPath(mPath, &strokePath);
171 Rect bounds = aTransform.TransformBounds(SkRectToRect(strokePath.getBounds()));
173 if (aPoint.x < bounds.x || aPoint.y < bounds.y ||
174 aPoint.x > bounds.XMost() || aPoint.y > bounds.YMost()) {
175 return false;
176 }
178 SkRegion pointRect;
179 pointRect.setRect(int32_t(SkFloatToScalar(transformed.x - 1)),
180 int32_t(SkFloatToScalar(transformed.y - 1)),
181 int32_t(SkFloatToScalar(transformed.x + 1)),
182 int32_t(SkFloatToScalar(transformed.y + 1)));
184 SkRegion pathRegion;
186 return pathRegion.setPath(strokePath, pointRect);
187 }
189 Rect
190 PathSkia::GetBounds(const Matrix &aTransform) const
191 {
192 Rect bounds = SkRectToRect(mPath.getBounds());
193 return aTransform.TransformBounds(bounds);
194 }
196 Rect
197 PathSkia::GetStrokedBounds(const StrokeOptions &aStrokeOptions,
198 const Matrix &aTransform) const
199 {
200 SkPaint paint;
201 StrokeOptionsToPaint(paint, aStrokeOptions);
203 SkPath result;
204 paint.getFillPath(mPath, &result);
206 Rect bounds = SkRectToRect(result.getBounds());
207 return aTransform.TransformBounds(bounds);
208 }
210 void
211 PathSkia::StreamToSink(PathSink *aSink) const
212 {
213 SkPath::RawIter iter(mPath);
215 SkPoint points[4];
216 SkPath::Verb currentVerb;
217 while ((currentVerb = iter.next(points)) != SkPath::kDone_Verb) {
218 switch (currentVerb) {
219 case SkPath::kMove_Verb:
220 aSink->MoveTo(SkPointToPoint(points[0]));
221 break;
222 case SkPath::kLine_Verb:
223 aSink->LineTo(SkPointToPoint(points[1]));
224 break;
225 case SkPath::kCubic_Verb:
226 aSink->BezierTo(SkPointToPoint(points[1]),
227 SkPointToPoint(points[2]),
228 SkPointToPoint(points[3]));
229 break;
230 case SkPath::kQuad_Verb:
231 aSink->QuadraticBezierTo(SkPointToPoint(points[1]),
232 SkPointToPoint(points[2]));
233 break;
234 case SkPath::kClose_Verb:
235 aSink->Close();
236 break;
237 default:
238 MOZ_ASSERT(false);
239 // Unexpected verb found in path!
240 }
241 }
242 }
244 }
245 }