Aspose.Slides for Java 20.9 Release Notes

New Features and Enhancements

KeySummaryCategory
SLIDESNET-42081Id attribute generating support for the individual tspan in SVGEnhancement

Other Improvements and Changes

KeySummaryCategory
SLIDESJAVA-38186Support for setting DPI of image when generating thumbnailFeature
SLIDESJAVA-37954Use Aspose.Slides for Net 20.9 featuresEnhancement
SLIDESJAVA-38146ArrayIndexOutOfBoundsException on saving presentationBug
SLIDESJAVA-38144PPT to PPTX back to PPT - the file gets increasingly biggerBug
SLIDESJAVA-37863Wrong text wrapping in generated HTMLBug
SLIDESJAVA-37732Text in exported HTML is misplacedBug
SLIDESJAVA-37646Output HTML file doesn’t match corresponding slideBug
SLIDESJAVA-37556Text improperly rendered in exported PDFBug
SLIDESJAVA-36879Thumbnails are not properly generatedBug
SLIDESJAVA-363753D rotation effects are missing in exported HTMLBug
SLIDESJAVA-35838Rotated text is not displayed correctly in resulted PDFBug

Public API Changes

3D Support has been added

We have created own cross-platform 3D engine in Aspose.Slides 20.9. Now it possible to create 3D presentations, 3D models, improve 2D shapes to 3D shapes.

Find more about 3D Presentation.

IBulletFormatEffectiveData.getFillFormat() method has been added

A new getFillFormat() method has been added to IBulletFormatEffectiveData interface. Using this method allows to get an effective value of paragraph bullet fill.

Method declaration:

/**
 * <p>
 * Returns the bullet fill format of a paragraph.
 * Read-only {@link IFillFormatEffectiveData}.
 * </p>
 */
public IFillFormatEffectiveData getFillFormat();

The code snippet below demonstrates retrieving bullet’s fill effective data:

Presentation pres = new Presentation("SomePresentation.pptx");
try {
    // Assume that the first shape on the first slide is AutoShape with some text...
    // Output information about text paragraphs' bullets
    AutoShape autoShape = (AutoShape)pres.getSlides().get_Item(0).getShapes().get_Item(0);
    for (IParagraph para : autoShape.getTextFrame().getParagraphs())
    {
        IBulletFormatEffectiveData bulletFormatEffective = para.getParagraphFormat().getBullet().getEffective();
        System.out.println("Bullet type: " + bulletFormatEffective.getType());
        if (bulletFormatEffective.getType() != BulletType.None)
        {
            System.out.println("Bullet fill type: " + bulletFormatEffective.getFillFormat().getFillType());
            switch (bulletFormatEffective.getFillFormat().getFillType())
            {
                case FillType.Solid:
                    System.out.println("Solid fill color: " + bulletFormatEffective.getFillFormat().getSolidFillColor());
                    break;
                case FillType.Gradient:
                    System.out.println("Gradient stops count: " + bulletFormatEffective.getFillFormat().getGradientFormat().getGradientStops().size());
                    for (IGradientStopEffectiveData gradStop : bulletFormatEffective.getFillFormat().getGradientFormat().getGradientStops())
                        System.out.println(gradStop.getPosition() + ": " + gradStop.getColor());
                    break;
                case FillType.Pattern:
                    System.out.println("Pattern style: " + bulletFormatEffective.getFillFormat().getPatternFormat().getPatternStyle());
                    System.out.println("Fore color: " + bulletFormatEffective.getFillFormat().getPatternFormat().getForeColor());
                    System.out.println("Back color: " + bulletFormatEffective.getFillFormat().getPatternFormat().getBackColor());
                    break;
            }
        }
        System.out.println();
    }
} finally {
    if (pres != null) pres.dispose();
}

Existing IBulletFormatEffectiveData.getColor() and IBulletFormatEffectiveData.getPicture() methods have been marked as obsolete and will be removed since Aspose.Slides 21.9 release. It is recommended to use IBulletFormatEffectiveData.getFillFormat().getSolidFillColor() and IBulletFormatEffectiveData.getFillFormat().getPictureFillFormat() methods instead, as they return the same data accordingly.

IBulletFormat.getEffective() method has been added

A new getEffective() method has been added to IBulletFormat interface and BulletFormat class. It allows to get an effective value of bullet formatting properties.

Method declaration:

/**
 * <p>
 * Gets effective bullet formatting data with the inheritance applied.
 * </p>
 */
public IBulletFormatEffectiveData getEffective();

The code snippet below demonstrates retrieving some of the bullet’s effective data:

Presentation pres = new Presentation("MyPresentation.pptx");
try {
    IAutoShape shape = (IAutoShape)pres.getSlides().get_Item(0).getShapes().get_Item(0);
    IBulletFormatEffectiveData effectiveBulletFormat = shape.getTextFrame().getParagraphs().get_Item(0).getParagraphFormat().getBullet().getEffective();
    System.out.println("Bullet type: " + effectiveBulletFormat.getType());
    if (effectiveBulletFormat.getType() == BulletType.Numbered)
    {
        System.out.println("Numbered style: " + effectiveBulletFormat.getNumberedBulletStyle());
        System.out.println("Starting number: " + effectiveBulletFormat.getNumberedBulletStartWith());
    }
} finally {
    if (pres != null) pres.dispose();
}

Please note that an existing way of getting bullet’s effective properties via IParagraph.createParagraphFormatEffective().getBullet() is also valid and still works.

Support for Id attribute generation for the individual tspan in SVG has been added

The ISvgShapeAndTextFormattingController interface, ISvgTSpan interface and SvgTSpan class have been added for tspan Id attribute manipulation in SVG.

ISvgShapeAndTextFormattingController declaration:

/**
 * <p>
 * Controls SVG shape and text generation.
 * </p><p><hr><blockquote><pre>Example:
 * <pre>
 */
public interface ISvgShapeAndTextFormattingController extends ISvgShapeFormattingController
{
    /**
     * <p>
     * This function is called before rendering of text portion to SVG to allow user to control resulting SVG.
     * </p>
     * @param svgTSpan Object to control SVG tspan generation.
     * @param portion Source portion.
     * @param textFrame Source portion text frame.
     */
    public void formatText(ISvgTSpan svgTSpan, IPortion portion, ITextFrame textFrame);
}

The code snippet below shows how to use ISvgShapeAndTextFormattingController interface:

public void SaveSlideToSVG() throws Exception
{
    Presentation pres = new Presentation(path + "presentation.pptx");
    try {
        SVGOptions svgOptions = new SVGOptions();
        svgOptions.setShapeFormattingController(new CustomSvgShapeFormattingController(0));

        FileOutputStream fs = new FileOutputStream(path + "slide.svg");
        try {
            pres.getSlides().get_Item(0).writeAsSvg(fs, svgOptions);
        } finally {
            if (fs != null) fs.close();
        }
    } finally {
        if (pres != null) pres.dispose();
    }
}

class CustomSvgShapeFormattingController implements ISvgShapeAndTextFormattingController
{
    private int m_shapeIndex, m_portionIndex, m_tspanIndex;

    public CustomSvgShapeFormattingController(int shapeStartIndex)
    {
        m_shapeIndex = shapeStartIndex;
        m_portionIndex = 0;
    }
    public void formatShape(ISvgShape svgShape, IShape shape)
    {
        svgShape.setId(String.format("shape-%d", m_shapeIndex++));
        m_portionIndex = m_tspanIndex = 0;
    }
    public void formatText(ISvgTSpan svgTSpan, IPortion portion, ITextFrame textFrame)
    {
        int paragraphIndex = 0; int portionIndex = 0;
        for (int i = 0; i < textFrame.getParagraphs().getCount(); i++)
        {
            portionIndex = textFrame.getParagraphs().get_Item(i).getPortions().indexOf(portion);
            if (portionIndex > -1) { paragraphIndex = i; break; }
        }
        if (m_portionIndex != portionIndex)
        {
            m_tspanIndex = 0;
            m_portionIndex = portionIndex;
        }
        svgTSpan.setId(String.format("paragraph-%d_portion-%d_%d", paragraphIndex, m_portionIndex, m_tspanIndex++));
    }
}