We're sorry Aspose doesn't work properply without JavaScript enabled.

Free Support Forum - aspose.com

Position of Shape inside GroupShape is not set correctly using C#

Hi Aspose support,
I have a question about positioning shapes inside GroupShape.
We have functionality that replaces Charts and SmartArts with images. For regular cases all works as expected in terms of replacing and image shape positioning in document.
But we have a problem with positioning image shape inside GroupShape - it always positions at the top left corner of a GroupShape, no matter whether Top and Left coordinates are set,
or copied from original object, on top of that I cannot even position original Chart/SmartArt (tried for testing purposes).

Here is the example of the document:
Group1.zip (59.7 KB)

It has a Chart which is placed little bit lower from top of GroupShape. When it’s replaced with image, image shows at the top left corner of a GroupShape. Imagine, if there’s more than one Chart,
they will be overlapped by each other at the same position.
BTW, within Word it is possible to set exact position for the shape inside the group.
Shapelayout.png (22.9 KB)

Code sample:

private void ReplaceShapes(Document doc, ImageSaveOptions options, DocumentBuilder builder)
{           
    NodeCollection shapes = doc.GetChildNodes(NodeType.Shape, true);
    // Loop from last one to first one
    for (int i = shapes.Count - 1; i >= 0; i--)
    {
        try
        {
            Shape shape = (Shape)shapes[i];

            if (!(shape.HasChart || shape.HasSmartArt)) continue;

            using (MemoryStream stream = new MemoryStream())
            {
                shape.GetShapeRenderer().Save(stream, options);

                // Shape in group case 
                if (shape.ParentNode.NodeType == NodeType.GroupShape)
                {
                    // Word creates fake group for Chart/SmartArt to group it with other objects
                    // and Word/Aspose does not allow insert objects into such fake group. 
                    // So, to insert/append an object need to use the group on one level up.
                    var fakeGroup = (GroupShape)shape.ParentNode;
                    // get real parent group
                    var parentGroup = (fakeGroup.ParentNode.NodeType == NodeType.GroupShape) ? (GroupShape)fakeGroup.ParentNode : null;
                    if (parentGroup != null)
                    {                                                                
                        // original shape has 0 size, so need to get size of parent ShapeGroup as it has valid size
                        Shape image = builder.InsertImage(stream, fakeGroup.SizeInPoints.Width, fakeGroup.SizeInPoints.Height);
                        if (image != null)
                        {                                                                           
                            parentGroup.AppendChild(image);                                    
                            image.RelativeHorizontalPosition = fakeGroup.RelativeHorizontalPosition;
                            image.RelativeVerticalPosition = fakeGroup.RelativeVerticalPosition;
                            image.Top = fakeGroup.Top;
                            image.Left = fakeGroup.Bottom;
                                                 
                            fakeGroup.Remove();   
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            // Ignore exception and continue process shapes collection                    
        }
    }
}
	
	public void Replace(Document doc)
{            
    try
    {
        // Save Charts and SmartArts into PNG format as optimal format for them
        ImageSaveOptions optionsPng = new ImageSaveOptions(SaveFormat.Png);
        optionsPng.Scale = 2;

        DocumentBuilder builder = new DocumentBuilder(_doc);

        ReplaceShapes(doc, optionsPng, builder);                
    }
    catch (Exception e)
    {
        //
    }
}

Unfortunately I wasn’t able to find answer on my problem on the forum.
Please advise, what can be wrong with this approach? What we’ve missed?

@licenses

Could you please ZIP and attach your problematic and expected output Word documents here for our reference? Please also share some more detail about the issue that you are facing. We will investigate the issue and provide you more information on it.

Hi @tahir.manzoor,
Sure, please see examples:
Example #1: Example1.zip (281.0 KB)

  • Group1.docx - original file with chart
    See Layout data:Group1_OriginalLayout.png (33.8 KB)

  • Group1_ConversionResult.docx - Problematic result of conversion/replacement produced by the code example in my previous post.
    As you can see layout data is incorrect: Group1_ConversionResultLayout.png (42.9 KB)

  • Group1_ExpectedResult.docx - Expected result of conversion/replacement.
    Layout data should be the same as for original chart: Group1_ExpectedResultLayout.png (44.3 KB)

Example #2: Example2.zip (180.0 KB)

  • GroupChartSmartArt.docx - original document with Chart and SmartArt in GroupShape
  • GroupChartSmartArt_ConversionResult.docx - problematic result of conversion/replacement, where shapes in GroupShape are overlapped. Produced by the code example in my previous post.
  • GroupChartSmartArt_ExpectedResult.docx - expected result for shapes layout inside GroupShape

Let me know if something else needs from my side.
Thanks.

@licenses

We have tested the scenario and have managed to reproduce the same issue at our side. For the sake of correction, we have logged this problem in our issue tracking system as WORDSNET-19125. You will be notified via this forum thread once this issue is resolved. We apologize for your inconvenience.

We are investigating this issue and will get back to you soon.

We have logged this problem in our issue tracking system as WORDSNET-19126 . You will be notified via this forum thread once this issue is resolved. We apologize for your inconvenience.

Thanks. Will wait for solution.

@licenses

Regarding WORDSNET-19126, we suggest you please use following method to get the desired output.

private static void ReplaceShapes(Document doc, ImageSaveOptions options, DocumentBuilder builder)
{
  NodeCollection shapes = doc.GetChildNodes(NodeType.Shape, true);
  // Loop from last one to first one
  for (int i = shapes.Count - 1; i >= 0; i--)
  {
    try
    {
      Shape shape = (Shape)shapes[i];

      if (!(shape.HasChart || shape.HasSmartArt))
        continue;

      using (MemoryStream stream = new MemoryStream())
      {
        shape.GetShapeRenderer().Save(stream, options);

        // Shape in group case 
        if (shape.ParentNode.NodeType == NodeType.GroupShape)
        {
          GroupShape graphicFrame = (GroupShape)shape.ParentNode;
          GroupShape parentGroup = (graphicFrame.ParentNode.NodeType == NodeType.GroupShape)
                                         ? (GroupShape)graphicFrame.ParentNode : null;

          if (parentGroup != null)
          {
             Shape image = builder.InsertImage(
                 stream,
                 graphicFrame.RelativeHorizontalPosition,
                 graphicFrame.Left,
                 graphicFrame.RelativeVerticalPosition,
                 graphicFrame.Top,
                 graphicFrame.SizeInPoints.Width,
                 graphicFrame.SizeInPoints.Height,
                 graphicFrame.WrapType);

             image.CoordOrigin = new Point(Convert.ToInt32(graphicFrame.Left), Convert.ToInt32(graphicFrame.Top));

             parentGroup.AppendChild(image);
             graphicFrame.Remove();
           }
         }
       }
     }
     catch (Exception e)
     {
        // Ignore exception and continue process shapes collection
     }
  }
}

Hi @tahir.manzoor,

Sorry for the delay with response.
Thanks for the code example.
Yes, the proposed solution works fine for me.
I even don’t know why I didn’t check this simple way, maybe because I thought that if clone settings from the original shape, then image shape will look similar (in idail world).
I think we can close the case.

@licenses

Thanks for your feedback. We have closed the issue WORDSNET-19126 as ‘Not a bug’.