gfx/2d/PathSkia.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

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 }

mercurial