본문 바로가기
SKIA

2.1.1 Canvas Clip Rect & Region

by SimonLee 2025. 5. 2.

 

1. 아래 모양을 렌더링 해보자.

void draw(SkCanvas* canvas) {
    SkPaint paint;
    for (SkClipOp op: { SkClipOp::kIntersect, SkClipOp::kDifference } ) {
        canvas->save();
        canvas->clipRect(SkRect::MakeWH(90, 120), op, false);
        canvas->drawCircle(100, 100, 60, paint);
        canvas->restore();
        canvas->translate(80, 0);
    }
}

kIntersect (교집합) : 초록색 부분

우측으로 80만큼 이동한 뒤

kDifference (차집합)  : 빨간색 부분

 


2. 아래 모양을 렌더링 해보자.

 

Antalias 적용 / 미적용

void draw(SkCanvas* canvas) {
    canvas->rotate(10);
    SkPaint paint;
    paint.setAntiAlias(true);
    for (auto alias: { false, true } ) {
        canvas->save();
        canvas->clipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, alias);
        canvas->drawCircle(100, 60, 60, paint);
        canvas->restore();
        canvas->translate(80, 0);
    }
}

 

canvas->rotate(10);

: 캔버스를 시계방향으로 10도 회전한다.

 

paint.setAntiAlias(true)

: antialias를 적용한다.

: paint 함수에도 setAntiAlias를 적용해야 저렇게 매끈하게 적용된다.

 

canvas->cliipRect(SkRect::MakeWH(90, 80), SkClipOp::kIntersect, true);

: 이전 클립 영역(전체영역)에서 사각형의 교차지역의 교집합 부분만 영역으로 설정한다.

 


3. 아래 모양을 렌더링 해보자.

void draw(SkCanvas* canvas) {
    canvas->clear(SK_ColorWHITE);
    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setColor(0x8055aaff);
    SkRect clipRect = { 0, 0, 87.4f, 87.4f };
    for (auto alias: { false, true } ) {
        canvas->save();
        canvas->clipRect(clipRect, SkClipOp::kIntersect, alias);
        canvas->drawCircle(67, 67, 60, paint);
        canvas->restore();
        canvas->save();
        canvas->clipRect(clipRect, SkClipOp::kDifference, alias);
        canvas->drawCircle(67, 67, 60, paint);
        canvas->restore();
        canvas->translate(120, 0);
    }
}

 

SkClipOp::kIntersect 는 사각형 내부 영역만 렌더링 

- 원과 교차영역 -> 빨강색 부분

SkClipOp::kDifference 는 사각형 외부 영역만 렌더링

- 사각형 바깥 영역과 원과 교차 영역 -> 파랑색 부분

둘다 렌더링 하게 되면 원이 그려진다.

 

첫번째 원과 두번째 원의 차이는 두번째 원의 내부의 하얀 경계선 같은것이 보인다.

alias 적용된 원이라서 그런지 선의 울퉁불퉁한 부분을 깍아 내는 효과를 만들면서

빈틈이 보인다.;;

 

SkPaint.setAntialias(true)

Fals로 하게 되면 원의 표면 픽셀이 울퉁불퉁해 진다.

 


  SkRect SkPath SkRegion
좌표 타입 float (부동소수점) float (부동소수점) int (정수)
형태 단일 사각형 임의의 도형 (선, 곡선, 복수 경로) 복수 개의 사각형 영역 집합 (Raster 기반)
복잡도 단순 (1개 사각형) 복잡한 도형 가능 (곡선, 복수 경로 등) 중간 복잡도 (사각형 조합)
변환(matrix) 적용됨 (rotate, scale 등 반영) 적용됨 적용 안 됨
클리핑 지원 canvas->clipRect() canvas->clipPath() canvas->clipRegion()
용도 간단한 사각형 영역 곡선/복잡한 경로 표현 정수 영역 기반 클리핑, 이산적 도형

 


4. 아래 모양을 렌더링 해보자.

void draw(SkCanvas* canvas) {
    SkPaint paint;
    paint.setAntiAlias(true);
    SkIRect iRect = {30, 40, 120, 130 };
    SkRegion region(iRect);
    canvas->rotate(10);
    canvas->save();
    canvas->clipRegion(region, SkClipOp::kIntersect);
    canvas->drawCircle(50, 50, 45, paint);
    canvas->restore();
    canvas->translate(100, 100);
    canvas->clipRect(SkRect::Make(iRect), SkClipOp::kIntersect);
    canvas->drawCircle(50, 50, 45, paint);
}

 

사각형 영역에 원영역의 교차 영역을 구하는 것은 동일하다.

SKRegion 의 경우는 matrix 변환을 무시한다.

그렇기에 clipRegion으로 클리핑한 영역은 회전이 되지 않는 것을 볼 수 있다.

 

SkIRect는 SkRect, SkRegion으로 변환 가능하다.

SkRect::Make(SkIRect iRect)

SkRegion::region(SkIRect iRect)

 


 

  clipRect cliprRRect clipPath
입력 타입 SkRect (사각형) SkRRect (둥근 사각형) SkPath (임의 곡선/도형)
지원 형태 직각 사각형만 모서리가 둥근 사각형만 (radius 포함) 곡선, 다각형, 비정형 경로 모두 가능

 

4. 아래 모양을 렌더링 해보자.

void draw(SkCanvas* canvas) {
    SkPaint paint;
    paint.setColor(0x8055aaff);
    paint.setAntiAlias(true);
    canvas->save();
    auto oval = SkRRect::MakeOval({0, 0, 90, 90});    	
    canvas->clipRRect(oval, SkClipOp::kIntersect, true);
    canvas->drawCircle(60, 60, 50, paint);
    canvas->restore();
}

 

SkRRect는 round rect로써, 모서리가 둥근 rect를 의미한다.

 

auto oval = SkRRect::MakeOval({0, 0, 90, 90});

ltfp (0, 0) ~ (90, 90) 영역에서 타원의 영역을 생성한다.

 

canvas->clipRect(oval, skClipOp::kIntersect, true);

타원의 영역을 렌더링 영역으로 설정한다. --> 빨강색 영역

 

canvas->drawCircle(60, 60, 50, paint);

원을 타원의 영역내에 그린다. --> 파랑색 영역과 빨강색의 교차 영역


5. 아래 모양을 렌더링 해보자

void draw(SkCanvas* canvas) {
    SkPaint paint;
    paint.setAntiAlias(true);
    auto oval = SkRRect::MakeRectXY({10, 20, 90, 100}, 9, 13);
    canvas->clipRRect(oval, true);
    canvas->drawCircle(70, 100, 60, paint);
}

 

SKRRect::MakeRectXY({10, 20, 90, 100}), 9, 13

- MakeRectXY는 LTRB 좌표(10, 20) ~ (90, 100)

- xRadius = 9 , yRadius = 13으로 구성되어 있다.

 

canvas->clipRRect(oval, true)

라운드 코너가 적용된 Rect가 클립영역으로 설정이 된다.

 

'SKIA' 카테고리의 다른 글

2.4 Canvas drawImage  (0) 2025.05.05
2.3 Canvas Drawable, DRRect  (0) 2025.05.05
2.1.0 Canvas Clip Path  (0) 2025.04.30
1. SkCanvas Overview  (0) 2025.04.29