Custom Shape
Change a Shape Using Edit Points
Consider a square. In PowerPoint, using edit points, you can
- move the square’s corner in or out
- specify the curvature for a corner or point
- add new points to the square
- manipulate points on the square, etc.
Essentially, you can perform the described tasks on any shape. Using edit points, you get to change a shape or create a new shape from an existing shape.
Shape Editing Tips
Before you start editing PowerPoint shapes through edit points, you might want to consider these points about shapes:
- A shape (or its path) can either be closed or open.
- When a shape is closed, it lacks a start or end point. When a shape is open, it has a beginning and end.
- All shapes consist of at least 2 anchor points linked to each other by lines
- A line is either straight or curved. Anchor points determine the nature of the line.
- Anchor points exist as corner points, straight points, or smooth points:
- A corner point is a point where 2 straight lines join at an angle.
- A smooth point is a point where 2 handles exist in a straight line and the line’s segments join in a smooth curve. In this case, all handles are separated from the anchor point by an equal distance.
- A straight point is a point where 2 handles exist in a straight line and that line’s line segments joins in a smooth curve. In this case, the handles don’t have to be separated from the anchor point by an equal distance.
- By moving or editing anchor points (which changes the angle of lines), you can change the way a shape looks.
To edit PowerPoint shapes through edit points, Aspose.Slides provides the GeometryPath class and IGeometryPath interface.
- A GeometryPath instance represents a geometry path of the IGeometryShape object
- To retrieve the
GeometryPath
from theIGeometryShape
instance, you can use the IGeometryShape.GetGeometryPaths method. - To set the
GeometryPath
for a shape, you can use these methods: IGeometryShape.SetGeometryPath for solid shapes and IGeometryShape.SetGeometryPaths for composite shapes. - To add segments, you can use the methods under IGeometryPath.
- Using the IGeometryPath.Stroke and IGeometryPath.FillMode properties, you can set the appearance for a geometry path.
- Using the IGeometryPath.PathData property, you can retrieve the geometry path of a
GeometryShape
as an array of path segments. - To access additional shape geometry customization options, you can convert GeometryPath to GraphicsPath.
- Use
GeometryPathToGraphicsPath
andGraphicsPathToGeometryPath
methods (from the ShapeUtil class) to convertGeometryPath
toGraphicsPath
back and forth.
Simple Editing Operations
This python code shows you how to
Add a line to the end of a path:
line_to(point)
line_to(x, y)
Add a line to a specified position on a path:
line_to(point, index)
line_to(x, y, index)
Add a cubic Bezier curve at the end of a path:
cubic_bezier_to(point1, point2, point3)
cubic_bezier_to(x1, y1, x2, y2, x3, y3)
Add a cubic Bezier curve to the specified position on a path:
cubic_bezier_to(point1, point2, point3, index)
cubic_bezier_to(x1, y1, x2, y2, x3, y3, index)
Add a quadratic Bezier curve at the end of a path:
quadratic_bezier_to(point1, point2)
quadratic_bezier_to(x1, y1, x2, y2)
Add quadratic Bezier curve to a specified position on a path:
quadratic_bezier_to(point1, point2, index)
quadratic_bezier_to(x1, y1, x2, y2, index)
Append a given arc to a path:
arc_to(width, heigth, startAngle, sweepAngle)
Close the current figure of a path:
close_figure()
Set the position for the next point:
move_to(point)
move_to(x, y)
Remove the path segment at a given index:
remove_at(index)
Add Custom Points to Shape
- Create an instance of the GeometryShape class and set the ShapeType.Rectangle
- Get an instance of the GeometryPath class from the shape.
- Add a new point between the two top points on the path.
- Add a new point between the two bottom points on the path.
- Apply the path to the shape.
This python code shows you how to add custom points to a shape:
import aspose.slides as slides
with slides.Presentation() as pres:
shape = pres.slides[0].shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 100, 100, 200, 100)
geometryPath = shape.get_geometry_paths()[0]
geometryPath.line_to(100, 50, 1)
geometryPath.line_to(100, 50, 4)
shape.set_geometry_path(geometryPath)
Remove Points from Shape
- Create an instance of the GeometryShape class of and set the ShapeType.Heart type.
- Get an instance of the GeometryPath class from the shape.
- Remove the segment for the path.
- Apply the path to the shape.
This python code shows you how to remove points from a shape:
import aspose.slides as slides
with slides.Presentation() as pres:
shape = pres.slides[0].shapes.add_auto_shape(slides.ShapeType.HEART, 100, 100, 300, 300)
path = shape.get_geometry_paths()[0]
path.remove_at(2)
shape.set_geometry_path(path)
Create Custom Shape
- Calculate points for the shape.
- Create an instance of the GeometryPath class.
- Fill the path with the points.
- Create an instance of the GeometryShape class.
- Apply the path to the shape.
This python code shows you how to create a custom shape:
import aspose.slides as slides
import aspose.pydrawing as draw
import math
points = []
R = 100
r = 50
step = 72
for angle in range(-90, 270, step):
radians = angle * (math.pi / 180)
x = R * math.cos(radians)
y = R * math.sin(radians)
points.append(draw.PointF(x + R, y + R))
radians = math.pi * (angle + step / 2) / 180.0
x = r * math.cos(radians)
y = r * math.sin(radians)
points.append(draw.PointF(x + R, y + R))
starPath = slides.GeometryPath()
starPath.move_to(points[0])
for i in range(len(points)):
starPath.line_to(points[i])
starPath.close_figure()
with slides.Presentation() as pres:
shape = pres.slides[0].shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 100, 100, R * 2, R * 2)
shape.set_geometry_path(starPath)
Create Composite Custom Shape
- Create an instance of the GeometryShape class.
- Create a first instance of the GeometryPath class.
- Create a second instance of the GeometryPath class.
- Apply the paths to the shape.
This python code shows you how to create a composite custom shape:
import aspose.slides as slides
import aspose.pydrawing as draw
with slides.Presentation() as pres:
shape = pres.slides[0].shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 100, 100, 200, 100)
geometryPath0 = slides.GeometryPath()
geometryPath0.move_to(0, 0)
geometryPath0.line_to(shape.width, 0)
geometryPath0.line_to(shape.width, shape.height/3)
geometryPath0.line_to(0, shape.height / 3)
geometryPath0.close_figure()
geometryPath1 = slides.GeometryPath()
geometryPath1.move_to(0, shape.height/3 * 2)
geometryPath1.line_to(shape.width, shape.height / 3 * 2)
geometryPath1.line_to(shape.width, shape.height)
geometryPath1.line_to(0, shape.height)
geometryPath1.close_figure()
shape.set_geometry_paths([ geometryPath0, geometryPath1])
Create Custom Shape With Curved Corners
This python code shows you how to create a custom shape with curved corners (inwards):
import aspose.slides as slides
import aspose.pydrawing as draw
shapeX = 20
shapeY = 20
shapeWidth = 300
shapeHeight = 200
leftTopSize = 50
rightTopSize = 20
rightBottomSize = 40
leftBottomSize = 10
with slides.Presentation() as presentation:
childShape = presentation.slides[0].shapes.add_auto_shape(
slides.ShapeType.CUSTOM, shapeX, shapeY, shapeWidth, shapeHeight)
geometryPath = slides.GeometryPath()
point1 = draw.PointF(leftTopSize, 0)
point2 = draw.PointF(shapeWidth - rightTopSize, 0)
point3 = draw.PointF(shapeWidth, shapeHeight - rightBottomSize)
point4 = draw.PointF(leftBottomSize, shapeHeight)
point5 = draw.PointF(0, leftTopSize)
geometryPath.move_to(point1)
geometryPath.line_to(point2)
geometryPath.arc_to(rightTopSize, rightTopSize, 180, -90)
geometryPath.line_to(point3)
geometryPath.arc_to(rightBottomSize, rightBottomSize, -90, -90)
geometryPath.line_to(point4)
geometryPath.arc_to(leftBottomSize, leftBottomSize, 0, -90)
geometryPath.line_to(point5)
geometryPath.arc_to(leftTopSize, leftTopSize, 90, -90)
geometryPath.close_figure()
childShape.set_geometry_path(geometryPath)
presentation.save("output.pptx", slides.export.SaveFormat.PPTX)
Find Out If a Shape Geometry Is Closed
A closed shape is defined as one where all its sides connect, forming a single boundary without gaps. Such a shape can be a simple geometric form or a complex custom outline. The following code example shows how to check if a shape geometry is closed:
def is_geometry_closed(geometry_shape):
is_closed = None
for geometry_path in geometry_shape.get_geometry_paths():
data_length = len(geometry_path.path_data)
if data_length == 0:
continue
last_segment = geometry_path.path_data[data_length - 1]
is_closed = last_segment.path_command == PathCommandType.CLOSE
if not is_closed:
return False
return is_closed
Conversion of GeometryPath to GraphicsPath (System.Drawing.Drawing2D)
- Create an instance of the GeometryShape class.
- Create an instance of the GrpahicsPath class of the System.Drawing.Drawing2D namespace.
- Convert the GraphicsPath instance to the GeometryPath instance using ShapeUtil.
- Apply the paths to the shape.
This python code—an implementation of the steps above—demonstrates the GeometryPath to GraphicsPath conversion process:
import aspose.slides as slides
import aspose.pydrawing as draw
with slides.Presentation() as pres:
shape = pres.slides[0].shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 100, 100, 300, 100)
originalPath = shape.get_geometry_paths()[0]
originalPath.fill_mode = slides.PathFillModeType.NONE
gPath = draw.drawing2d.GraphicsPath()
gPath.add_string("Text in shape", draw.FontFamily("Arial"), 1, 40, draw.PointF(10, 10), draw.StringFormat.generic_default)
textPath = slides.util.ShapeUtil.graphics_path_to_geometry_path(gPath)
textPath.fill_mode = slides.PathFillModeType.NORMAL
shape.set_geometry_paths([originalPath, textPath])