Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 0c073bf

Browse files
committed
[[ ClipToPath ]] Implement clip to path
This patch implements a new statement in the lcb canvas library to clip to a path. Previously only setting a clipping rectangle was supported however this patch allows for more complext cliping paths. It additionally simplifies the clipping of images as there is no need to create a pattern paint from them and fill a path.
1 parent e32934f commit 0c073bf

File tree

6 files changed

+58
-0
lines changed

6 files changed

+58
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# LiveCode Builder Host Library
2+
## Canvas library
3+
4+
A new statement `clip to <path> on <canvas>` has been implemented to allow drawing on a
5+
canvas to be clipped to the path. Previously the clip region could only be set to a
6+
rectangle via the `clip to <rectangle> on <canvas>` statement.
7+
8+
For example to draw an image into a circle:
9+
10+
clip to circle path centered at point [my width /2,my height / 2] with radius my width/2 on this canvas
11+
variable tImage as Image
12+
put image from resource file "foo.png" into tImage
13+
draw tImage into rectangle [0, 0, the width of tImage, the height of tImage] of this canvas

engine/src/canvas.lcb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4288,6 +4288,7 @@ public foreign handler MCCanvasFillPath(in pPath as Path, in pCanvas as Canvas)
42884288
public foreign handler MCCanvasStroke(in pCanvas as Canvas) returns nothing binds to "<builtin>"
42894289
public foreign handler MCCanvasStrokePath(in pPath as Path, in pCanvas as Canvas) returns nothing binds to "<builtin>"
42904290
public foreign handler MCCanvasClipToRect(in pClip as Rectangle, in pCanvas as Canvas) returns nothing binds to "<builtin>"
4291+
public foreign handler MCCanvasClipToPath(in pClip as Path, in pCanvas as Canvas) returns nothing binds to "<builtin>"
42914292
public foreign handler MCCanvasAddPath(in pPath as Path, in pCanvas as Canvas) returns nothing binds to "<builtin>"
42924293
public foreign handler MCCanvasDrawImage(in pImage as Image, in pDest as Rectangle, in pCanvas as Canvas) returns nothing binds to "<builtin>"
42934294
public foreign handler MCCanvasDrawRectOfImage(in pSrc as Rectangle, in pImage as Image, in pDst as Rectangle, in pCanvas as Canvas) returns nothing binds to "<builtin>"
@@ -4612,6 +4613,31 @@ end syntax
46124613

46134614
//////////
46144615

4616+
/**
4617+
Summary: Clip to a path on a canvas.
4618+
4619+
mCanvas: An expression which evaluates to a canvas.
4620+
mPath: An expression which evaluates to a path.
4621+
4622+
Description: Modifies the clip of <mCanvas> by intersecting with <mRect>. Drawing operations on <mCanvas> will be confined to the clip region.
4623+
4624+
Example:
4625+
// Set the canvas clip
4626+
clip to circle path centered at point [100,100] with radius 50 on this canvas
4627+
4628+
// Fill rectangle path on canvas. only the region of the rectangle that falls within the canvas clip will be rendered.
4629+
fill rectangle path of rectangle [25, 25, 75, 75] on this canvas
4630+
4631+
Tags: Canvas
4632+
*/
4633+
syntax CanvasOperationClipPath is statement
4634+
"clip" "to" <mPath: Expression> "on" <mCanvas: Expression>
4635+
begin
4636+
MCCanvasClipToPath(mPath, mCanvas)
4637+
end syntax
4638+
4639+
//////////
4640+
46154641
/**
46164642
Summary: Add a path to a canvas.
46174643

engine/src/module-canvas.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5781,6 +5781,15 @@ void MCCanvasClipToRect(MCCanvasRectangleRef p_rect, MCCanvasRef p_canvas)
57815781
MCGContextClipToRect(t_canvas->context, *MCCanvasRectangleGet(p_rect));
57825782
}
57835783

5784+
MC_DLLEXPORT_DEF
5785+
void MCCanvasClipToPath(MCCanvasPathRef p_path, MCCanvasRef p_canvas)
5786+
{
5787+
__MCCanvasImpl *t_canvas;
5788+
t_canvas = MCCanvasGet(p_canvas);
5789+
5790+
MCGContextClipToPath(t_canvas->context, *MCCanvasPathGet(p_path));
5791+
}
5792+
57845793
MC_DLLEXPORT_DEF
57855794
void MCCanvasAddPath(MCCanvasPathRef p_path, MCCanvasRef p_canvas)
57865795
{

engine/src/module-canvas.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ extern "C" MC_DLLEXPORT void MCCanvasFillPath(MCCanvasPathRef p_path, MCCanvasRe
569569
extern "C" MC_DLLEXPORT void MCCanvasStroke(MCCanvasRef p_canvas);
570570
extern "C" MC_DLLEXPORT void MCCanvasStrokePath(MCCanvasPathRef p_path, MCCanvasRef p_canvas);
571571
extern "C" MC_DLLEXPORT void MCCanvasClipToRect(MCCanvasRectangleRef p_rect, MCCanvasRef p_canvas);
572+
extern "C" MC_DLLEXPORT void MCCanvasClipToPath(MCCanvasPathRef p_path, MCCanvasRef p_canvas);
572573
extern "C" MC_DLLEXPORT void MCCanvasAddPath(MCCanvasPathRef p_path, MCCanvasRef p_canvas);
573574
extern "C" MC_DLLEXPORT void MCCanvasDrawImage(MCCanvasImageRef p_image, MCCanvasRectangleRef p_dst_rect, MCCanvasRef p_canvas);
574575
extern "C" MC_DLLEXPORT void MCCanvasDrawRectOfImage(MCCanvasRectangleRef p_src_rect, MCCanvasImageRef p_image, MCCanvasRectangleRef p_dst_rect, MCCanvasRef p_canvas);

libgraphics/include/graphics.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,7 @@ void MCGContextBeginWithEffects(MCGContextRef context, MCGRectangle shape, const
925925
void MCGContextEnd(MCGContextRef context);
926926

927927
void MCGContextClipToRect(MCGContextRef context, MCGRectangle rect);
928+
void MCGContextClipToPath(MCGContextRef context, MCGPathRef path);
928929
void MCGContextSetClipToRect(MCGContextRef context, MCGRectangle rect);
929930
MCGRectangle MCGContextGetClipBounds(MCGContextRef context);
930931
MCGRectangle MCGContextGetDeviceClipBounds(MCGContextRef context);

libgraphics/src/context.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,14 @@ void MCGContextClipToRect(MCGContextRef self, MCGRectangle p_rect)
13401340
self -> layer -> canvas -> clipRect(MCGRectangleToSkRect(p_rect), SkRegion::kIntersect_Op, self -> state -> should_antialias);
13411341
}
13421342

1343+
void MCGContextClipToPath(MCGContextRef self, MCGPathRef p_path)
1344+
{
1345+
if (!MCGContextIsValid(self) || !MCGPathIsValid(p_path))
1346+
return;
1347+
1348+
self -> layer -> canvas -> clipPath(*p_path -> path, SkRegion::kIntersect_Op, self -> state -> should_antialias);
1349+
}
1350+
13431351
void MCGContextSetClipToDeviceRegion(MCGContextRef self, MCGRegionRef p_region)
13441352
{
13451353
if (!MCGContextIsValid(self) || p_region == nil)

0 commit comments

Comments
 (0)