Personalizar Formas de Apresentação em C++
Visão geral
Este artigo explica como personalizar formas de apresentação no Aspose.Slides editando a geometria da forma por meio de pontos de edição e caminhos de geometria. Ele demonstra como trabalhar com GeometryPath e IGeometryPath para modificar formas existentes, executar operações básicas de edição de caminho, adicionar ou remover pontos e aplicar a geometria atualizada de volta a uma forma.
Alterar uma Forma Usando Pontos de Edição
Considere um quadrado. No PowerPoint, usando pontos de edição, você pode
- mover o canto do quadrado para dentro ou para fora
- especificar a curvatura de um canto ou ponto
- adicionar novos pontos ao quadrado
- manipular pontos no quadrado, etc.
Basicamente, você pode executar as tarefas descritas em qualquer forma. Usando pontos de edição, você pode alterar uma forma ou criar uma nova forma a partir de uma forma existente.
Dicas para Edição de Formas

Antes de começar a editar formas do PowerPoint por meio de pontos de edição, considere os seguintes aspectos sobre formas:
- Uma forma (ou seu caminho) pode ser fechada ou aberta.
- Quando uma forma está fechada, não possui ponto inicial ou final. Quando uma forma está aberta, tem um início e um fim.
- Todas as formas consistem em, no mínimo, 2 pontos de ancoragem ligados entre si por linhas.
- Uma linha pode ser reta ou curva. Os pontos de ancoragem determinam a natureza da linha.
- Pontos de ancoragem podem ser pontos de canto, pontos retos ou pontos suaves:
- Um ponto de canto é um ponto onde 2 linhas retas se unem em um ângulo.
- Um ponto suave é um ponto onde 2 alças existem em uma linha reta e os segmentos da linha se juntam em uma curva suave. Nesse caso, todas as alças ficam separadas do ponto de ancoragem por uma distância igual.
- Um ponto reto é um ponto onde 2 alças existem em uma linha reta e os segmentos da linha se juntam em uma curva suave. Nesse caso, as alças não precisam estar separadas do ponto de ancoragem por uma distância igual.
- Ao mover ou editar pontos de ancoragem (o que altera o ângulo das linhas), você pode mudar a aparência de uma forma.
Para editar formas do PowerPoint por meio de pontos de edição, Aspose.Slides fornece a classe GeometryPath e a interface IGeometryPath.
- Uma instância de GeometryPath representa o caminho de geometria do objeto IGeometryShape.
- Para obter o
GeometryPatha partir da instânciaIGeometryShape, você pode usar o método IGeometryShape::GetGeometryPaths. - Para definir o
GeometryPathde uma forma, você pode usar estes métodos: IGeometryShape::SetGeometryPath() para formas sólidas e IGeometryShape::SetGeometryPaths() para formas compostas. - Para adicionar segmentos, você pode usar os métodos da interface IGeometryPath.
- Usando os métodos IGeometryPath::set_Stroke() e IGeometryPath::set_FillMode(), você pode definir a aparência de um caminho de geometria.
- Usando o método IGeometryPath::get_PathData(), você pode recuperar o caminho de geometria de um
GeometryShapecomo um array de segmentos de caminho. - Para acessar opções adicionais de personalização da geometria da forma, você pode converter GeometryPath para GraphicsPath.
- Use os métodos GeometryPathToGraphicsPath e GraphicsPathToGeometryPath (da classe ShapeUtil) para converter GeometryPath em GraphicsPath e vice‑versa.
Operações Simples de Edição
Este código C++ mostra como
Adicionar uma linha ao final de um caminho
void LineTo(PointF point);
void LineTo(float x, float y);
Adicionar uma linha em uma posição especificada no caminho:
void LineTo(PointF point, uint32_t index);
void LineTo(float x, float y, uint32_t index);
Adicionar uma curva cúbica de Bézier ao final de um caminho:
void CubicBezierTo(PointF point1, PointF point2, PointF point3);
void CubicBezierTo(float x1, float y1, float x2, float y2, float x3, float y3);
Adicionar uma curva cúbica de Bézier na posição especificada do caminho:
void CubicBezierTo(PointF point1, PointF point2, PointF point3, uint32_t index);
void CubicBezierTo(float x1, float y1, float x2, float y2, float x3, float y3, uint32_t index);
Adicionar uma curva quadrática de Bézier ao final de um caminho:
void QuadraticBezierTo(PointF point1, PointF point2);
void QuadraticBezierTo(float x1, float y1, float x2, float y2);
Adicionar uma curva quadrática de Bézier a uma posição especificada no caminho:
void QuadraticBezierTo(PointF point1, PointF point2, uint32_t index);
void QuadraticBezierTo(float x1, float y1, float x2, float y2, uint32_t index);
Anexar um arco ao caminho:
void ArcTo(float width, float heigth, float startAngle, float sweepAngle);
Fechar a figura atual de um caminho:
void CloseFigure();
Definir a posição do próximo ponto:
void MoveTo(PointF point);
void MoveTo(float x, float y);
Remover o segmento de caminho em um índice determinado:
void RemoveAt(int32_t index);
Adicionar Pontos Personalizados a uma Forma
- Crie uma instância da classe GeometryShape e defina o tipo ShapeType.Rectangle.
- Obtenha uma instância da classe GeometryPath a partir da forma.
- Adicione um novo ponto entre os dois pontos superiores do caminho.
- Adicione um novo ponto entre os dois pontos inferiores do caminho.
- Aplique o caminho à forma.
Este código C++ mostra como adicionar pontos personalizados a uma forma:
SharedPtr<Presentation> pres = System::MakeObject<Presentation>();
SharedPtr<IShapeCollection> shapes = pres->get_Slides()->idx_get(0)->get_Shapes();
SharedPtr<GeometryShape> shape = System::ExplicitCast<GeometryShape>(shapes->AddAutoShape(ShapeType::Rectangle, 100.0f, 100.0f, 200.0f, 100.0f));
SharedPtr<IGeometryPath> geometryPath = shape->GetGeometryPaths()->idx_get(0);
geometryPath->LineTo(100.0f, 50.0f, 1);
geometryPath->LineTo(100.0f, 50.0f, 4);
shape->SetGeometryPath(geometryPath);

Remover Pontos de uma Forma
- Crie uma instância da classe GeometryShape e defina o tipo ShapeType.Heart.
- Obtenha uma instância da classe GeometryPath a partir da forma.
- Remova o segmento do caminho.
- Aplique o caminho à forma.
Este código C++ mostra como remover pontos de uma forma:
SharedPtr<Presentation> pres = System::MakeObject<Presentation>();
SharedPtr<IShapeCollection> shapes = pres->get_Slides()->idx_get(0)->get_Shapes();
SharedPtr<GeometryShape> shape = System::ExplicitCast<GeometryShape>(shapes->AddAutoShape(ShapeType::Heart, 100.0f, 100.0f, 300.0f, 300.0f));
SharedPtr<IGeometryPath> path = shape->GetGeometryPaths()->idx_get(0);
path->RemoveAt(2);
shape->SetGeometryPath(path);

Criar uma Forma Personalizada
- Calcule os pontos da forma.
- Crie uma instância da classe GeometryPath.
- Preencha o caminho com os pontos.
- Crie uma instância da classe GeometryShape.
- Aplique o caminho à forma.
Este código C++ mostra como criar uma forma personalizada:
SharedPtr<List<PointF>> points = System::MakeObject<List<PointF>>();
float R = 100.0f, r = 50.0f;
int32_t step = 72;
for (int32_t angle = -90; angle < 270; angle += step)
{
double radians = angle * (Math::PI / 180.f);
double x = outerRadius * Math::Cos(radians);
double y = outerRadius * Math::Sin(radians);
points->Add(PointF((float)x + outerRadius, (float)y + outerRadius));
radians = Math::PI * (angle + step / 2) / 180.0;
x = innerRadiusr * Math::Cos(radians);
y = innerRadiusr * Math::Sin(radians);
points->Add(PointF((float)x + outerRadius, (float)y + outerRadius));
}
SharedPtr<GeometryPath> starPath = System::MakeObject<GeometryPath>();
starPath->MoveTo(points->idx_get(0));
for (int32_t i = 1; i < points->get_Count(); i++)
{
starPath->LineTo(points->idx_get(i));
}
starPath->CloseFigure();
SharedPtr<Presentation> pres = System::MakeObject<Presentation>();
SharedPtr<IShapeCollection> shapes = pres->get_Slides()->idx_get(0)->get_Shapes();
SharedPtr<GeometryShape> shape = System::ExplicitCast<GeometryShape>(shapes->AddAutoShape(ShapeType::Rectangle, 100.0f, 100.0f, R * 2, R * 2));
shape->SetGeometryPath(starPath);

Criar uma Forma Personalizada Composta
- Crie uma instância da classe GeometryShape.
- Crie a primeira instância da classe GeometryPath.
- Crie a segunda instância da classe GeometryPath.
- Aplique os caminhos à forma.
Este código C++ mostra como criar uma forma personalizada composta:
SharedPtr<Presentation> pres = System::MakeObject<Presentation>();
SharedPtr<IShapeCollection> shapes = pres->get_Slides()->idx_get(0)->get_Shapes();
SharedPtr<GeometryShape> shape = System::ExplicitCast<GeometryShape>(shapes->AddAutoShape(ShapeType::Rectangle, 100.0f, 100.0f, 200.0f, 100.0f));
SharedPtr<IGeometryPath> geometryPath0 = System::MakeObject<GeometryPath>();
geometryPath0->MoveTo(0.0f, 0.0f);
geometryPath0->LineTo(shape->get_Width(), 0.0f);
geometryPath0->LineTo(shape->get_Width(), shape->get_Height() / 3);
geometryPath0->LineTo(0.0f, shape->get_Height() / 3);
geometryPath0->CloseFigure();
SharedPtr<IGeometryPath> geometryPath1 = System::MakeObject<GeometryPath>();
geometryPath1->MoveTo(0.0f, shape->get_Height() / 3 * 2);
geometryPath1->LineTo(shape->get_Width(), shape->get_Height() / 3 * 2);
geometryPath1->LineTo(shape->get_Width(), shape->get_Height());
geometryPath1->LineTo(0.0f, shape->get_Height());
geometryPath1->CloseFigure();
shape->SetGeometryPaths(System::MakeArray<SharedPtr<IGeometryPath>>({ geometryPath0, geometryPath1 }));

Criar uma Forma Personalizada com Cantos Curvos
Este código C++ mostra como criar uma forma personalizada com cantos curvos (inward):
float shapeX = 20.f;
float shapeY = 20.f;
float shapeWidth = 300.f;
float shapeHeight = 200.f;
float leftTopSize = 50.f;
float rightTopSize = 20.f;
float rightBottomSize = 40.f;
float leftBottomSize = 10.f;
auto presentation = System::MakeObject<Presentation>();
auto childShape = presentation->get_Slides()->idx_get(0)->get_Shapes()->AddAutoShape(ShapeType::Custom, shapeX, shapeY, shapeWidth, shapeHeight);
auto geometryPath = System::MakeObject<GeometryPath>();
PointF point1(leftTopSize, 0.0f);
PointF point2(shapeWidth - rightTopSize, 0.0f);
PointF point3(shapeWidth, shapeHeight - rightBottomSize);
PointF point4(leftBottomSize, shapeHeight);
PointF point5(0.0f, leftTopSize);
geometryPath->MoveTo(point1);
geometryPath->LineTo(point2);
geometryPath->ArcTo(rightTopSize, rightTopSize, 180.0f, -90.0f);
geometryPath->LineTo(point3);
geometryPath->ArcTo(rightBottomSize, rightBottomSize, -90.0f, -90.0f);
geometryPath->LineTo(point4);
geometryPath->ArcTo(leftBottomSize, leftBottomSize, 0.0f, -90.0f);
geometryPath->LineTo(point5);
geometryPath->ArcTo(leftTopSize, leftTopSize, 90.0f, -90.0f);
geometryPath->CloseFigure();
childShape->SetGeometryPath(geometryPath);
presentation->Save(u"output.pptx", SaveFormat::Pptx);
Descobrir Se a Geometria de uma Forma Está Fechada
Uma forma fechada é definida como aquela em que todos os lados se conectam, formando um único contorno sem lacunas. Essa forma pode ser um simples contorno geométrico ou um delineamento personalizado complexo. O exemplo de código a seguir demonstra como verificar se a geometria de uma forma está fechada:
bool IsGeometryClosed(SharedPtr<IGeometryShape> geometryShape)
{
bool isClosed = false;
for (auto&& geometryPath : geometryShape->GetGeometryPaths())
{
auto dataLength = geometryPath->get_PathData()->get_Length();
if (dataLength == 0)
continue;
auto lastSegment = geometryPath->get_PathData()[dataLength - 1];
isClosed = lastSegment->get_PathCommand() == PathCommandType::Close;
if (!isClosed)
return false;
}
return isClosed;
}
Converter GeometryPath para GraphicsPath
- Crie uma instância da classe GeometryShape.
- Crie uma instância da classe GraphicsPath do namespace System.Drawing.Drawing2D.
- Converta a instância de GraphicsPath para a instância de GeometryPath usando a classe ShapeUtil.
- Aplique os caminhos à forma.
Este código C++ — implementação dos passos acima — demonstra o processo de conversão de GeometryPath para GraphicsPath:
SharedPtr<Presentation> pres = System::MakeObject<Presentation>();
SharedPtr<IShapeCollection> shapes = pres->get_Slides()->idx_get(0)->get_Shapes();
SharedPtr<GeometryShape> shape = System::ExplicitCast<GeometryShape>(shapes->AddAutoShape(ShapeType::Rectangle, 100.0f, 100.0f, 300.0f, 100.0f));
SharedPtr<IGeometryPath> originalPath = shape->GetGeometryPaths()->idx_get(0);
originalPath->set_FillMode(PathFillModeType::None);
SharedPtr<Drawing2D::GraphicsPath> graphicsPath = System::MakeObject<Drawing2D::GraphicsPath>();
graphicsPath->AddString(u"Text in shape", System::MakeObject<FontFamily>(u"Arial"), 1, 40.0f, PointF(10.0f, 10.0f), StringFormat::get_GenericDefault());
SharedPtr<IGeometryPath> textPath = ShapeUtil::GraphicsPathToGeometryPath(graphicsPath);
textPath->set_FillMode(PathFillModeType::Normal);
shape->SetGeometryPaths(System::MakeArray<SharedPtr<IGeometryPath>>({ originalPath, textPath }));

FAQ
O que acontecerá com o preenchimento e o contorno após substituir a geometria?
O estilo permanece associado à forma; somente o contorno muda. O preenchimento e o contorno são aplicados automaticamente à nova geometria.
Como girar corretamente uma forma personalizada junto com sua geometria?
Use a propriedade rotation da forma; a geometria gira com a forma porque está vinculada ao próprio sistema de coordenadas da forma.
Posso converter uma forma personalizada em uma imagem para “travar” o resultado?
Sim. Exporte a área do slide necessária ou o próprio shape para um formato raster; isso simplifica o trabalho posterior com geometrias pesadas.