Flutter iOS Embedder
FlutterClippingMaskView Class Reference

#import <FlutterPlatformViews_Internal.h>

Inheritance diagram for FlutterClippingMaskView:

Instance Methods

(instancetype) - initWithFrame:screenScale:
 
(void) - reset
 
(void) - clipRect:matrix:
 
(void) - clipRRect:matrix:
 
(void) - clipPath:matrix:
 

Detailed Description

Definition at line 35 of file FlutterPlatformViews_Internal.h.

Method Documentation

◆ clipPath:matrix:

- (void) clipPath: (const SkPath&)  path
matrix: (const SkMatrix&)  matrix 

Definition at line 371 of file FlutterPlatformViews_Internal.mm.

371  :(const SkPath&)path matrix:(const SkMatrix&)matrix {
372  if (!path.isValid()) {
373  return;
374  }
375  if (path.isEmpty()) {
376  return;
377  }
378  containsNonRectPath_ = YES;
379  CGMutablePathRef pathRef = CGPathCreateMutable();
380 
381  // Loop through all verbs and translate them into CGPath
382  SkPath::Iter iter(path, true);
383  SkPoint pts[kMaxPointsInVerb];
384  SkPath::Verb verb = iter.next(pts);
385  SkPoint last_pt_from_last_verb = SkPoint::Make(0, 0);
386  while (verb != SkPath::kDone_Verb) {
387  if (verb == SkPath::kLine_Verb || verb == SkPath::kQuad_Verb || verb == SkPath::kConic_Verb ||
388  verb == SkPath::kCubic_Verb) {
389  FML_DCHECK(last_pt_from_last_verb == pts[0]);
390  }
391  switch (verb) {
392  case SkPath::kMove_Verb: {
393  CGPathMoveToPoint(pathRef, nil, pts[0].x(), pts[0].y());
394  last_pt_from_last_verb = pts[0];
395  break;
396  }
397  case SkPath::kLine_Verb: {
398  CGPathAddLineToPoint(pathRef, nil, pts[1].x(), pts[1].y());
399  last_pt_from_last_verb = pts[1];
400  break;
401  }
402  case SkPath::kQuad_Verb: {
403  CGPathAddQuadCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y());
404  last_pt_from_last_verb = pts[2];
405  break;
406  }
407  case SkPath::kConic_Verb: {
408  // Conic is not available in quartz, we use quad to approximate.
409  // TODO(cyanglaz): Better approximate the conic path.
410  // https://github.com/flutter/flutter/issues/35062
411  CGPathAddQuadCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y());
412  last_pt_from_last_verb = pts[2];
413  break;
414  }
415  case SkPath::kCubic_Verb: {
416  CGPathAddCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y(),
417  pts[3].x(), pts[3].y());
418  last_pt_from_last_verb = pts[3];
419  break;
420  }
421  case SkPath::kClose_Verb: {
422  CGPathCloseSubpath(pathRef);
423  break;
424  }
425  case SkPath::kDone_Verb: {
426  break;
427  }
428  }
429  verb = iter.next(pts);
430  }
431  // The `matrix` is based on the physical pixels, convert it to UIKit points.
432  CATransform3D matrixInPoints =
433  CATransform3DConcat(GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale);
434  paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]);
435 }

References containsNonRectPath_.

◆ clipRect:matrix:

- (void) clipRect: (const SkRect&)  clipSkRect
matrix: (const SkMatrix&)  matrix 

Definition at line 285 of file FlutterPlatformViews_Internal.mm.

285  :(const SkRect&)clipSkRect matrix:(const SkMatrix&)matrix {
286  CGRect clipRect = GetCGRectFromSkRect(clipSkRect);
287  CGPathRef path = CGPathCreateWithRect(clipRect, nil);
288  // The `matrix` is based on the physical pixels, convert it to UIKit points.
289  CATransform3D matrixInPoints =
290  CATransform3DConcat(GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale);
291  paths_.push_back([self getTransformedPath:path matrix:matrixInPoints]);
292  CGAffineTransform affine = [self affineWithMatrix:matrixInPoints];
293  // Make sure the rect is not rotated (only translated or scaled).
294  if (affine.b == 0 && affine.c == 0) {
295  rectSoFar_ = CGRectIntersection(rectSoFar_, CGRectApplyAffineTransform(clipRect, affine));
296  } else {
297  containsNonRectPath_ = YES;
298  }
299 }

References containsNonRectPath_, and rectSoFar_.

Referenced by clipRRect:matrix:.

◆ clipRRect:matrix:

- (void) clipRRect: (const SkRRect&)  clipSkRRect
matrix: (const SkMatrix&)  matrix 

Definition at line 301 of file FlutterPlatformViews_Internal.mm.

301  :(const SkRRect&)clipSkRRect matrix:(const SkMatrix&)matrix {
302  containsNonRectPath_ = YES;
303  CGPathRef pathRef = nullptr;
304  switch (clipSkRRect.getType()) {
305  case SkRRect::kEmpty_Type: {
306  break;
307  }
308  case SkRRect::kRect_Type: {
309  [self clipRect:clipSkRRect.rect() matrix:matrix];
310  return;
311  }
312  case SkRRect::kOval_Type:
313  case SkRRect::kSimple_Type: {
314  CGRect clipRect = GetCGRectFromSkRect(clipSkRRect.rect());
315  pathRef = CGPathCreateWithRoundedRect(clipRect, clipSkRRect.getSimpleRadii().x(),
316  clipSkRRect.getSimpleRadii().y(), nil);
317  break;
318  }
319  case SkRRect::kNinePatch_Type:
320  case SkRRect::kComplex_Type: {
321  CGMutablePathRef mutablePathRef = CGPathCreateMutable();
322  // Complex types, we manually add each corner.
323  SkRect clipSkRect = clipSkRRect.rect();
324  SkVector topLeftRadii = clipSkRRect.radii(SkRRect::kUpperLeft_Corner);
325  SkVector topRightRadii = clipSkRRect.radii(SkRRect::kUpperRight_Corner);
326  SkVector bottomRightRadii = clipSkRRect.radii(SkRRect::kLowerRight_Corner);
327  SkVector bottomLeftRadii = clipSkRRect.radii(SkRRect::kLowerLeft_Corner);
328 
329  // Start drawing RRect
330  // Move point to the top left corner adding the top left radii's x.
331  CGPathMoveToPoint(mutablePathRef, nil, clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop);
332  // Move point horizontally right to the top right corner and add the top right curve.
333  CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fRight - topRightRadii.x(),
334  clipSkRect.fTop);
335  CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fRight, clipSkRect.fTop,
336  clipSkRect.fRight, clipSkRect.fTop + topRightRadii.y(),
337  clipSkRect.fRight, clipSkRect.fTop + topRightRadii.y());
338  // Move point vertically down to the bottom right corner and add the bottom right curve.
339  CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fRight,
340  clipSkRect.fBottom - bottomRightRadii.y());
341  CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fRight, clipSkRect.fBottom,
342  clipSkRect.fRight - bottomRightRadii.x(), clipSkRect.fBottom,
343  clipSkRect.fRight - bottomRightRadii.x(), clipSkRect.fBottom);
344  // Move point horizontally left to the bottom left corner and add the bottom left curve.
345  CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fLeft + bottomLeftRadii.x(),
346  clipSkRect.fBottom);
347  CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fLeft, clipSkRect.fBottom,
348  clipSkRect.fLeft, clipSkRect.fBottom - bottomLeftRadii.y(),
349  clipSkRect.fLeft, clipSkRect.fBottom - bottomLeftRadii.y());
350  // Move point vertically up to the top left corner and add the top left curve.
351  CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fLeft,
352  clipSkRect.fTop + topLeftRadii.y());
353  CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fLeft, clipSkRect.fTop,
354  clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop,
355  clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop);
356  CGPathCloseSubpath(mutablePathRef);
357 
358  pathRef = mutablePathRef;
359  break;
360  }
361  }
362  // The `matrix` is based on the physical pixels, convert it to UIKit points.
363  CATransform3D matrixInPoints =
364  CATransform3DConcat(GetCATransform3DFromSkMatrix(matrix), _reverseScreenScale);
365  // TODO(cyanglaz): iOS does not seem to support hard edge on CAShapeLayer. It clearly stated that
366  // the CAShaperLayer will be drawn antialiased. Need to figure out a way to do the hard edge
367  // clipping on iOS.
368  paths_.push_back([self getTransformedPath:pathRef matrix:matrixInPoints]);
369 }

References clipRect:matrix:, and containsNonRectPath_.

◆ initWithFrame:screenScale:

- (instancetype) initWithFrame: (CGRect)  frame
screenScale: (CGFloat)  screenScale 

Definition at line 216 of file FlutterPlatformViews_Internal.mm.

216  :(CGRect)frame screenScale:(CGFloat)screenScale {
217  if (self = [super initWithFrame:frame]) {
218  self.backgroundColor = UIColor.clearColor;
219  _reverseScreenScale = CATransform3DMakeScale(1 / screenScale, 1 / screenScale, 1);
220  rectSoFar_ = self.bounds;
222  }
223  return self;
224 }

References containsNonRectPath_, initWithFrame, and rectSoFar_.

◆ reset

- (void) reset

Definition at line 234 of file FlutterPlatformViews_Internal.mm.

234  {
235  paths_.clear();
236  rectSoFar_ = self.bounds;
238  [self shapeLayer].path = nil;
239  [self setNeedsDisplay];
240 }

References containsNonRectPath_, and rectSoFar_.


The documentation for this class was generated from the following files:
containsNonRectPath_
BOOL containsNonRectPath_
Definition: FlutterPlatformViews_Internal.mm:206
initWithFrame
instancetype initWithFrame
Definition: FlutterTextInputPlugin.h:172
rectSoFar_
CGRect rectSoFar_
Definition: FlutterPlatformViews_Internal.mm:209