5#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h"
7#include "flutter/display_list/effects/dl_image_filter.h"
8#include "flutter/fml/platform/darwin/cf_utils.h"
9#import "flutter/shell/platform/darwin/ios/ios_surface.h"
19 std::unique_ptr<IOSSurface> ios_surface,
20 std::unique_ptr<Surface>
surface)
21 : overlay_view(overlay_view),
22 overlay_view_wrapper(overlay_view_wrapper),
23 ios_surface(
std::move(ios_surface)),
31 mask_view_pool_.
reset(
38 return weak_factory_->GetWeakPtr();
43 CATransform3D
transform = CATransform3DIdentity;
58 layer.anchorPoint = CGPointZero;
59 layer.position = CGPointZero;
68 const CGFloat epsilon = 0.01;
69 return radius1 - radius2 < epsilon;
77@property(nonatomic)
BOOL backdropFilterViewConfigured;
82- (void)updateVisualEffectView:(UIVisualEffectView*)visualEffectView;
96 blurRadius:(CGFloat)blurRadius
97 visualEffectView:(UIVisualEffectView*)visualEffectView {
98 if (
self = [super init]) {
103 FML_DLOG(
ERROR) <<
"Apple's API for UIVisualEffectView changed. Update the implementation to "
104 "access the gaussianBlur CAFilter.";
108 _backdropFilterView = [visualEffectView retain];
109 _backdropFilterViewConfigured = NO;
116 [_gaussianBlurFilter release];
122+ (void)prepareOnce:(UIVisualEffectView*)visualEffectView {
126 for (NSUInteger i = 0; i < visualEffectView.subviews.count; i++) {
127 UIView* view = visualEffectView.subviews[i];
128 if ([NSStringFromClass([view
class]) hasSuffix:
@"BackdropView"]) {
130 for (NSObject* filter in view.layer.filters) {
131 if ([[filter valueForKey:
@"name"] isEqual:
@"gaussianBlur"] &&
132 [[filter valueForKey:
@"inputRadius"] isKindOfClass:[NSNumber class]]) {
137 }
else if ([NSStringFromClass([view
class]) hasSuffix:
@"VisualEffectSubview"]) {
149 [_backdropFilterView release];
150 _backdropFilterView = nil;
157 if (!
self.backdropFilterViewConfigured) {
158 [
self updateVisualEffectView:_backdropFilterView];
159 self.backdropFilterViewConfigured = YES;
161 return _backdropFilterView;
164- (void)updateVisualEffectView:(UIVisualEffectView*)visualEffectView {
165 NSObject* gaussianBlurFilter = [[_gaussianBlurFilter copy] autorelease];
167 UIView* backdropView = visualEffectView.subviews[_indexOfBackdropView];
168 [gaussianBlurFilter setValue:@(_blurRadius) forKey:@"inputRadius"];
169 backdropView.layer.filters = @[ gaussianBlurFilter ];
171 UIView* visualEffectSubview = visualEffectView.subviews[_indexOfVisualEffectSubview];
172 visualEffectSubview.layer.backgroundColor = UIColor.clearColor.CGColor;
173 visualEffectView.frame = _frame;
175 if (_backdropFilterView != visualEffectView) {
176 _backdropFilterView = [visualEffectView retain];
184@property(retain, nonatomic) NSArray<PlatformViewFilter*>* filters;
194- (
BOOL)pointInside:(CGPoint)point withEvent:(
UIEvent*)event {
195 for (UIView* view in
self.subviews) {
196 if ([view pointInside:[
self convertPoint:point toView:view] withEvent:
event]) {
205 if (
self.filters.count == 0 && filters.count == 0) {
208 self.filters = filters;
209 NSUInteger index = 0;
210 for (index = 0; index <
self.filters.count; index++) {
211 UIVisualEffectView* backdropFilterView;
213 if (
self.backdropFilterSubviews.count <= index) {
214 backdropFilterView = filter.backdropFilterView;
215 [self addSubview:backdropFilterView];
216 [self.backdropFilterSubviews addObject:backdropFilterView];
218 [filter updateVisualEffectView:self.backdropFilterSubviews[index]];
221 for (NSUInteger i =
self.backdropFilterSubviews.count; i > index; i--) {
222 [
self.backdropFilterSubviews[i - 1] removeFromSuperview];
223 [
self.backdropFilterSubviews removeLastObject];
231 [_backdropFilterSubviews release];
232 _backdropFilterSubviews = nil;
238 if (!_backdropFilterSubviews) {
239 _backdropFilterSubviews = [[NSMutableArray alloc] init];
241 return _backdropFilterSubviews;
256@property(nonatomic) CATransform3D reverseScreenScale;
258- (
fml::CFRef<CGPathRef>)getTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix;
263 std::vector<fml::CFRef<CGPathRef>> paths_;
267 return [
self initWithFrame:frame screenScale:[UIScreen mainScreen].scale];
270- (instancetype)
initWithFrame:(CGRect)frame screenScale:(CGFloat)screenScale {
272 self.backgroundColor = UIColor.clearColor;
273 _reverseScreenScale = CATransform3DMakeScale(1 / screenScale, 1 / screenScale, 1);
280 [
self setNeedsDisplay];
288- (
BOOL)pointInside:(CGPoint)point withEvent:(
UIEvent*)event {
292- (void)drawRect:(CGRect)rect {
293 CGContextRef context = UIGraphicsGetCurrentContext();
294 CGContextSaveGState(context);
297 CGContextSetAlpha(context, 1);
299 for (
size_t i = 0; i < paths_.size(); i++) {
300 CGContextAddPath(context, paths_.at(i));
301 CGContextClip(context);
303 CGContextFillRect(context, rect);
304 CGContextRestoreGState(context);
309 CGPathRef
path = CGPathCreateWithRect(clipRect, nil);
311 CATransform3D matrixInPoints =
313 paths_.push_back([
self getTransformedPath:
path matrix:matrixInPoints]);
317 CGPathRef pathRef =
nullptr;
318 switch (clipSkRRect.
getType()) {
323 [
self clipRect:clipSkRRect.rect() matrix:matrix];
329 pathRef = CGPathCreateWithRoundedRect(clipRect, clipSkRRect.
getSimpleRadii().
x(),
335 CGMutablePathRef mutablePathRef = CGPathCreateMutable();
345 CGPathMoveToPoint(mutablePathRef, nil, clipSkRect.
fLeft + topLeftRadii.
x(), clipSkRect.
fTop);
347 CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.
fRight - topRightRadii.
x(),
349 CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.
fRight, clipSkRect.
fTop,
350 clipSkRect.
fRight, clipSkRect.
fTop + topRightRadii.
y(),
351 clipSkRect.
fRight, clipSkRect.
fTop + topRightRadii.
y());
353 CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.
fRight,
354 clipSkRect.
fBottom - bottomRightRadii.
y());
355 CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.
fRight, clipSkRect.
fBottom,
359 CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.
fLeft + bottomLeftRadii.
x(),
361 CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.
fLeft, clipSkRect.
fBottom,
365 CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.
fLeft,
366 clipSkRect.
fTop + topLeftRadii.
y());
367 CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.
fLeft, clipSkRect.
fTop,
368 clipSkRect.
fLeft + topLeftRadii.
x(), clipSkRect.
fTop,
369 clipSkRect.
fLeft + topLeftRadii.
x(), clipSkRect.
fTop);
370 CGPathCloseSubpath(mutablePathRef);
372 pathRef = mutablePathRef;
377 CATransform3D matrixInPoints =
382 paths_.push_back([
self getTransformedPath:pathRef
matrix:matrixInPoints]);
386 if (!
path.isValid()) {
389 if (
path.isEmpty()) {
392 CGMutablePathRef pathRef = CGPathCreateMutable();
406 CGPathMoveToPoint(pathRef, nil, pts[0].
x(), pts[0].
y());
407 last_pt_from_last_verb = pts[0];
411 CGPathAddLineToPoint(pathRef, nil, pts[1].
x(), pts[1].
y());
412 last_pt_from_last_verb = pts[1];
416 CGPathAddQuadCurveToPoint(pathRef, nil, pts[1].
x(), pts[1].
y(), pts[2].
x(), pts[2].
y());
417 last_pt_from_last_verb = pts[2];
424 CGPathAddQuadCurveToPoint(pathRef, nil, pts[1].
x(), pts[1].
y(), pts[2].
x(), pts[2].
y());
425 last_pt_from_last_verb = pts[2];
429 CGPathAddCurveToPoint(pathRef, nil, pts[1].
x(), pts[1].
y(), pts[2].
x(), pts[2].
y(),
430 pts[3].
x(), pts[3].
y());
431 last_pt_from_last_verb = pts[3];
435 CGPathCloseSubpath(pathRef);
442 verb = iter.next(pts);
445 CATransform3D matrixInPoints =
447 paths_.push_back([
self getTransformedPath:pathRef
matrix:matrixInPoints]);
450- (
fml::CFRef<CGPathRef>)getTransformedPath:(CGPathRef)path matrix:(CATransform3D)matrix {
451 CGAffineTransform affine =
453 CGPathRef transformedPath = CGPathCreateCopyByTransformingPath(path, &affine);
464@property(assign, nonatomic) NSUInteger capacity;
468@property(retain, nonatomic) NSMutableSet<FlutterClippingMaskView*>*
pool;
474- (instancetype)initWithCapacity:(NSInteger)capacity {
475 if (
self = [super init]) {
478 _pool = [[NSMutableSet alloc] initWithCapacity:1];
479 _capacity = capacity;
486 if (
self.pool.count == 0) {
490 screenScale:[UIScreen mainScreen].scale] autorelease];
493 maskView.frame =
frame;
495 [
self.pool removeObject:maskView];
502 if (
self.pool.count ==
self.capacity) {
505 [
self.pool addObject:maskView];
SkVector getSimpleRadii() const
const SkRect & rect() const
SkVector radii(Corner corner) const
@ kOval_Type
non-zero width and height filled with radii
@ kSimple_Type
non-zero width and height with equal radii
@ kEmpty_Type
zero width or height
@ kNinePatch_Type
non-zero width and height with axis-aligned radii
@ kRect_Type
non-zero width and height, and zeroed radii
@ kComplex_Type
non-zero width and height with arbitrary radii
@ kUpperLeft_Corner
index of top-left corner radii
@ kLowerRight_Corner
index of bottom-right corner radii
@ kUpperRight_Corner
index of top-right corner radii
@ kLowerLeft_Corner
index of bottom-left corner radii
void reset(NST *object=Traits::InvalidValue(), scoped_policy::OwnershipPolicy policy=scoped_policy::OwnershipPolicy::kAssume)
#define FML_DLOG(severity)
#define FML_DCHECK(condition)
NSMutableArray * backdropFilterSubviews()
instancetype initWithFrame
clipRRect(r.rrect, r.opAA.op(), r.opAA.aa())) DRAW(ClipRect
unsigned useCenter Optional< SkMatrix > matrix
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
clipPath(r.path, r.opAA.op(), r.opAA.aa())) DRAW(ClipRRect
BOOL BlurRadiusEqualToBlurRadius(CGFloat radius1, CGFloat radius2)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
void ResetAnchor(CALayer *layer)
CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix &matrix)
CGRect GetCGRectFromSkRect(const SkRect &clipSkRect)
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
static constexpr SkPoint Make(float x, float y)
constexpr float y() const
constexpr float x() const
SkScalar fBottom
larger y-axis bounds
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
SkScalar fTop
smaller y-axis bounds