Skip to content

Commit dff5f69

Browse files
author
Monte Goulding
authored
Merge pull request livecode#6549 from montegoulding/cliptopath
[[ ClipToPath ]] Implement clip to path
2 parents 56b3e6c + 0c073bf commit dff5f69

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
@@ -5785,6 +5785,15 @@ void MCCanvasClipToRect(MCCanvasRectangleRef p_rect, MCCanvasRef p_canvas)
57855785
MCGContextClipToRect(t_canvas->context, *MCCanvasRectangleGet(p_rect));
57865786
}
57875787

5788+
MC_DLLEXPORT_DEF
5789+
void MCCanvasClipToPath(MCCanvasPathRef p_path, MCCanvasRef p_canvas)
5790+
{
5791+
__MCCanvasImpl *t_canvas;
5792+
t_canvas = MCCanvasGet(p_canvas);
5793+
5794+
MCGContextClipToPath(t_canvas->context, *MCCanvasPathGet(p_path));
5795+
}
5796+
57885797
MC_DLLEXPORT_DEF
57895798
void MCCanvasAddPath(MCCanvasPathRef p_path, MCCanvasRef p_canvas)
57905799
{

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
@@ -937,6 +937,7 @@ void MCGContextBeginWithEffects(MCGContextRef context, MCGRectangle shape, const
937937
void MCGContextEnd(MCGContextRef context);
938938

939939
void MCGContextClipToRect(MCGContextRef context, MCGRectangle rect);
940+
void MCGContextClipToPath(MCGContextRef context, MCGPathRef path);
940941
void MCGContextSetClipToRect(MCGContextRef context, MCGRectangle rect);
941942
MCGRectangle MCGContextGetClipBounds(MCGContextRef context);
942943
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)