Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkPathOpsTightBounds.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
10#include "include/core/SkRect.h"
14#include "src/core/SkPathPriv.h"
20
21#include <algorithm>
22
23bool TightBounds(const SkPath& path, SkRect* result) {
25 bool wellBehaved = true;
26 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
27 switch (verb) {
29 moveBounds.fLeft = std::min(moveBounds.fLeft, pts[0].fX);
30 moveBounds.fTop = std::min(moveBounds.fTop, pts[0].fY);
31 moveBounds.fRight = std::max(moveBounds.fRight, pts[0].fX);
32 moveBounds.fBottom = std::max(moveBounds.fBottom, pts[0].fY);
33 break;
36 if (!wellBehaved) {
37 break;
38 }
39 wellBehaved &= between(pts[0].fX, pts[1].fX, pts[2].fX);
40 wellBehaved &= between(pts[0].fY, pts[1].fY, pts[2].fY);
41 break;
43 if (!wellBehaved) {
44 break;
45 }
46 wellBehaved &= between(pts[0].fX, pts[1].fX, pts[3].fX);
47 wellBehaved &= between(pts[0].fY, pts[1].fY, pts[3].fY);
48 wellBehaved &= between(pts[0].fX, pts[2].fX, pts[3].fX);
49 wellBehaved &= between(pts[0].fY, pts[2].fY, pts[3].fY);
50 break;
51 default:
52 break;
53 }
54 }
55 if (wellBehaved) {
56 *result = path.getBounds();
57 return true;
58 }
59 SkSTArenaAlloc<4096> allocator; // FIXME: constant-ize, tune
61 SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
62 SkOpGlobalState globalState(contourList, &allocator SkDEBUGPARAMS(false)
63 SkDEBUGPARAMS(nullptr));
64 // turn path into list of segments
65 SkOpEdgeBuilder builder(path, contourList, &globalState);
66 if (!builder.finish()) {
67 return false;
68 }
69 if (!SortContourList(&contourList, false, false)) {
70 *result = moveBounds;
71 return true;
72 }
73 SkOpContour* current = contourList;
74 SkPathOpsBounds bounds = current->bounds();
75 while ((current = current->next())) {
76 bounds.add(current->bounds());
77 }
78 *result = bounds;
79 if (!moveBounds.isEmpty()) {
80 result->join(moveBounds);
81 }
82 return true;
83}
static bool between(SkScalar a, SkScalar b, SkScalar c)
bool SortContourList(SkOpContourHead **contourList, bool evenOdd, bool oppEvenOdd)
#define SkDEBUGPARAMS(...)
bool TightBounds(const SkPath &path, SkRect *result)
@ kCubic
SkPath::RawIter returns 4 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
#define SK_ScalarMin
Definition SkScalar.h:25
#define SK_ScalarMax
Definition SkScalar.h:24
const SkPathOpsBounds & bounds() const
Definition SkOpContour.h:68
SkOpContour * next()
GAsyncResult * result
SkScalar w
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
bool isEmpty() const
Definition SkRect.h:693
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15