Personalizar formas de presentación en Java
Cambiar una forma usando puntos de edición
Considere un cuadrado. En PowerPoint, usando puntos de edición, puede
- mover la esquina del cuadrado hacia adentro o hacia afuera
- especificar la curvatura de una esquina o punto
- agregar nuevos puntos al cuadrado
- manipular puntos en el cuadrado, etc.
Esencialmente, puede realizar las tareas descritas en cualquier forma. Usando puntos de edición, puede cambiar una forma o crear una nueva forma a partir de una forma existente.
Consejos para la edición de formas

Antes de comenzar a editar formas de PowerPoint mediante puntos de edición, quizá quiera considerar los siguientes aspectos sobre las formas:
- Una forma (o su ruta) puede ser cerrada o abierta.
- Cuando una forma es cerrada, carece de un punto de inicio o final. Cuando una forma es abierta, tiene un comienzo y un final.
- Todas las formas constan de al menos 2 puntos de anclaje vinculados entre sí por líneas
- Una línea puede ser recta o curva. Los puntos de anclaje determinan la naturaleza de la línea.
- Los puntos de anclaje existen como puntos de esquina, puntos rectos o puntos suaves:
- Un punto de esquina es un punto donde se unen 2 líneas rectas formando un ángulo.
- Un punto suave es un punto donde existen 2 manejadores en una línea recta y los segmentos de la línea se unen en una curva suave. En este caso, todos los manejadores están separados del punto de anclaje por una distancia igual.
- Un punto recto es un punto donde existen 2 manejadores en una línea recta y los segmentos de esa línea se unen en una curva suave. En este caso, los manejadores no tienen que estar separados del punto de anclaje por una distancia igual.
- Al mover o editar los puntos de anclaje (lo que cambia el ángulo de las líneas), puede modificar la apariencia de una forma.
Para editar formas de PowerPoint mediante puntos de edición, Aspose.Slides ofrece la clase GeometryPath y la interfaz IGeometryPath.
- Una instancia de GeometryPath representa una ruta geométrica del objeto IGeometryShape.
- Para obtener el
GeometryPathde la instanciaIGeometryShape, puede usar el método IGeometryShape.getGeometryPaths. - Para establecer el
GeometryPathde una forma, puede usar estos métodos: IGeometryShape.setGeometryPath para formas sólidas y IGeometryShape.setGeometryPaths para formas compuestas. - Para agregar segmentos, puede usar los métodos bajo IGeometryPath.
- Usando los métodos IGeometryPath.setStroke y IGeometryPath.setFillMode, puede establecer la apariencia de una ruta geométrica.
- Usando el método IGeometryPath.getPathData puede obtener la ruta geométrica de un
GeometryShapecomo una matriz de segmentos de ruta. - Para acceder a opciones adicionales de personalización de la geometría de forma, puede convertir GeometryPath a java.awt.Shape
- Use los métodos geometryPathToGraphicsPath y graphicsPathToGeometryPath (de la clase ShapeUtil) para convertir GeometryPath a java.awt.Shape y viceversa.
Operaciones de edición simples
Este código Java le muestra cómo
Agregar una línea al final de una ruta
public void lineTo(java.awt.geom.Point2D.Float point);
public void lineTo(float x, float y);
Agregar una línea a una posición especificada en una ruta:
public void lineTo(java.awt.geom.Point2D.Float point, long index);
public void lineTo(float x, float y, long index);
Agregar una curva Bézier cúbica al final de una ruta:
public void cubicBezierTo(java.awt.geom.Point2D.Float point1, java.awt.geom.Point2D.Float point2, java.awt.geom.Point2D.Float point3);
public void cubicBezierTo(float x1, float y1, float x2, float y2, float x3, float y3);
Agregar una curva Bézier cúbica a la posición especificada en una ruta:
public void cubicBezierTo(java.awt.geom.Point2D.Float point1, java.awt.geom.Point2D.Float point2, java.awt.geom.Point2D.Float point3, long index);
public void cubicBezierTo(float x1, float y1, float x2, float y2, float x3, float y3, long index);
Agregar una curva Bézier cuadrática al final de una ruta:
public void quadraticBezierTo(java.awt.geom.Point2D.Float point1, java.awt.geom.Point2D.Float point2);
public void quadraticBez
ierTo(float x1, float y1, float x2, float y2);
Agregar una curva Bézier cuadrática a una posición especificada en una ruta:
public void quadraticBezierTo(java.awt.geom.Point2D.Float point1, java.awt.geom.Point2D.Float point2, long index);
public void quadraticBezierTo(float x1, float y1, float x2, float y2, long index);
Añadir un arco dado a una ruta:
public void arcTo(float width, float heigth, float startAngle, float sweepAngle);
Cerrar la figura actual de una ruta:
public void closeFigure();
Establecer la posición para el siguiente punto:
public void moveTo(java.awt.geom.Point2D.Float point);
public void moveTo(float x, float y);
Eliminar el segmento de ruta en un índice dado:
public void removeAt(int index);
Agregar puntos personalizados a una forma
- Cree una instancia de la clase GeometryShape y establezca el tipo ShapeType.Rectangle.
- Obtenga una instancia de la clase GeometryPath de la forma.
- Añada un nuevo punto entre los dos puntos superiores de la ruta.
- Añada un nuevo punto entre los dos puntos inferiores de la ruta.
- Aplique la ruta a la forma.
Este código Java le muestra cómo agregar puntos personalizados a una forma:
Presentation pres = new Presentation();
try {
GeometryShape shape = (GeometryShape) pres.getSlides().get_Item(0).
getShapes().addAutoShape(ShapeType.Rectangle, 100, 100, 200, 100);
IGeometryPath geometryPath = shape.getGeometryPaths()[0];
geometryPath.lineTo(100, 50, 1);
geometryPath.lineTo(100, 50, 4);
shape.setGeometryPath(geometryPath);
} finally {
if (pres != null) pres.dispose();
}

Eliminar puntos de una forma
- Cree una instancia de la clase GeometryShape y establezca el tipo ShapeType.Heart.
- Obtenga una instancia de la clase GeometryPath de la forma.
- Elimine el segmento de la ruta.
- Aplique la ruta a la forma.
Este código Java le muestra cómo eliminar puntos de una forma:
Presentation pres = new Presentation();
try {
GeometryShape shape = (GeometryShape) pres.getSlides().get_Item(0).
getShapes().addAutoShape(ShapeType.Heart, 100, 100, 300, 300);
IGeometryPath path = shape.getGeometryPaths()[0];
path.removeAt(2);
shape.setGeometryPath(path);
} finally {
if (pres != null) pres.dispose();
}

Crear una forma personalizada
- Calcule los puntos para la forma.
- Cree una instancia de la clase GeometryPath.
- Rellene la ruta con los puntos.
- Cree una instancia de la clase GeometryShape.
- Aplique la ruta a la forma.
Este Java le muestra cómo crear una forma personalizada:
List<Point2D.Float> points = new ArrayList<Point2D.Float>();
float R = 100, r = 50;
int step = 72;
for (int angle = -90; angle < 270; angle += step)
{
double radians = angle * (Math.PI / 180f);
double x = R * Math.cos(radians);
double y = R * Math.sin(radians);
points.add(new Point2D.Float((float)x + R, (float)y + R));
radians = Math.PI * (angle + step / 2) / 180.0;
x = r * Math.cos(radians);
y = r * Math.sin(radians);
points.add(new Point2D.Float((float)x + R, (float)y + R));
}
GeometryPath starPath = new GeometryPath();
starPath.moveTo(points.get(0));
for (int i = 1; i < points.size(); i++)
{
starPath.lineTo(points.get(i));
}
starPath.closeFigure();
Presentation pres = new Presentation();
try {
GeometryShape shape = (GeometryShape) pres.getSlides().get_Item(0).
getShapes().addAutoShape(ShapeType.Rectangle, 100, 100, R * 2, R * 2);
shape.setGeometryPath(starPath);
} finally {
if (pres != null) pres.dispose();
}

Crear una forma personalizada compuesta
- Cree una instancia de la clase GeometryShape.
- Cree una primera instancia de la clase GeometryPath.
- Cree una segunda instancia de la clase GeometryPath.
- Aplique las rutas a la forma.
Este código Java le muestra cómo crear una forma personalizada compuesta:
Presentation pres = new Presentation();
try {
GeometryShape shape = (GeometryShape) pres.getSlides().get_Item(0).
getShapes().addAutoShape(ShapeType.Rectangle, 100, 100, 200, 100);
GeometryPath geometryPath0 = new GeometryPath();
geometryPath0.moveTo(0, 0);
geometryPath0.lineTo(shape.getWidth(), 0);
geometryPath0.lineTo(shape.getWidth(), shape.getHeight()/3);
geometryPath0.lineTo(0, shape.getHeight() / 3);
geometryPath0.closeFigure();
GeometryPath geometryPath1 = new GeometryPath();
geometryPath1.moveTo(0, shape.getHeight()/3 * 2);
geometryPath1.lineTo(shape.getWidth(), shape.getHeight() / 3 * 2);
geometryPath1.lineTo(shape.getWidth(), shape.getHeight());
geometryPath1.lineTo(0, shape.getHeight());
geometryPath1.closeFigure();
shape.setGeometryPaths(new GeometryPath[] { geometryPath0, geometryPath1});
} finally {
if (pres != null) pres.dispose();
}

Crear una forma personalizada con esquinas curvas
Este código Java le muestra cómo crear una forma personalizada con esquinas curvas (hacia adentro);
float shapeX = 20f;
float shapeY = 20f;
float shapeWidth = 300f;
float shapeHeight = 200f;
float leftTopSize = 50f;
float rightTopSize = 20f;
float rightBottomSize = 40f;
float leftBottomSize = 10f;
Presentation pres = new Presentation();
try {
IAutoShape childShape = pres.getSlides().get_Item(0).getShapes().addAutoShape(
ShapeType.Custom, shapeX, shapeY, shapeWidth, shapeHeight);
GeometryPath geometryPath = new GeometryPath();
Point2D.Float point1 = new Point2D.Float(leftTopSize, 0);
Point2D.Float point2 = new Point2D.Float(shapeWidth - rightTopSize, 0);
Point2D.Float point3 = new Point2D.Float(shapeWidth, shapeHeight - rightBottomSize);
Point2D.Float point4 = new Point2D.Float(leftBottomSize, shapeHeight);
Point2D.Float point5 = new Point2D.Float(0, leftTopSize);
geometryPath.moveTo(point1);
geometryPath.lineTo(point2);
geometryPath.arcTo(rightTopSize, rightTopSize, 180, -90);
geometryPath.lineTo(point3);
geometryPath.arcTo(rightBottomSize, rightBottomSize, -90, -90);
geometryPath.lineTo(point4);
geometryPath.arcTo(leftBottomSize, leftBottomSize, 0, -90);
geometryPath.lineTo(point5);
geometryPath.arcTo(leftTopSize, leftTopSize, 90, -90);
geometryPath.closeFigure();
childShape.setGeometryPath(geometryPath);
pres.save("output.pptx", SaveFormat.Pptx);
} finally {
if (pres!= null) pres.dispose();
}
Descubrir si la geometría de una forma está cerrada
Una forma cerrada se define como aquella en la que todos sus lados se conectan, formando un solo contorno sin huecos. Esa forma puede ser una forma geométrica simple o un contorno personalizado complejo. El siguiente ejemplo de código muestra cómo verificar si la geometría de una forma está cerrada:
boolean isGeometryClosed(IGeometryShape geometryShape)
{
Boolean isClosed = null;
for (IGeometryPath geometryPath : geometryShape.getGeometryPaths()) {
int dataLength = geometryPath.getPathData().length;
if (dataLength == 0)
continue;
IPathSegment lastSegment = geometryPath.getPathData()[dataLength - 1];
isClosed = lastSegment.getPathCommand() == PathCommandType.Close;
if (isClosed == false)
return false;
}
return isClosed == true;
}
Convertir GeometryPath a java.awt.Shape
- Cree una instancia de la clase GeometryShape.
- Cree una instancia de la clase java.awt.Shape.
- Convierta la instancia java.awt.Shape a la instancia GeometryPath usando ShapeUtil.
- Aplique las rutas a la forma.
Este código Java—una implementación de los pasos anteriores—demuestra el proceso de conversión de GeometryPath a GraphicsPath:
Presentation pres = new Presentation();
try {
// Crear nueva forma
GeometryShape shape = (GeometryShape)pres.getSlides().get_Item(0).
getShapes().addAutoShape(ShapeType.Rectangle, 100, 100, 300, 100);
// Obtener la ruta de geometría de la forma
IGeometryPath originalPath = shape.getGeometryPaths()[0];
originalPath.setFillMode(PathFillModeType.None);
// Crear nueva ruta gráfica con texto
Shape graphicsPath;
Font font = new java.awt.Font("Arial", Font.PLAIN, 40);
String text = "Text in shape";
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
try
{
GlyphVector glyphVector = font.createGlyphVector(g2.getFontRenderContext(), text);
graphicsPath = glyphVector.getOutline(20f, ((float) -glyphVector.getVisualBounds().getY()) + 10);
}
finally {
g2.dispose();
}
// Convertir ruta gráfica a ruta de geometría
IGeometryPath textPath = ShapeUtil.graphicsPathToGeometryPath(graphicsPath);
textPath.setFillMode(PathFillModeType.Normal);
// Establecer combinación de la nueva ruta de geometría y la ruta de geometría original en la forma
shape.setGeometryPaths(new IGeometryPath[] { originalPath, textPath });
} finally {
if (pres != null) pres.dispose();
}

FAQ
¿Qué sucederá con el relleno y el contorno después de reemplazar la geometría?
El estilo permanece con la forma; solo el contorno cambia. El relleno y el contorno se aplican automáticamente a la nueva geometría.
¿Cómo rotar correctamente una forma personalizada junto con su geometría?
Utilice el método setRotation de la forma; la geometría gira con la forma porque está vinculada al propio sistema de coordenadas de la forma.
¿Puedo convertir una forma personalizada en una imagen para “bloquear” el resultado?
Sí. Exporte el área de la diapositiva requerida o la propia forma a un formato raster; esto simplifica el trabajo posterior con geometrías complejas.