Пример #1
0
        private void DrawShape(Wpg.WordprocessingGroup wordprocessingGroup, Rect cmlExtents, A.ShapeTypeValues shape, string colour)
        {
            UInt32Value id           = UInt32Value.FromUInt32((uint)m_ooxmlId++);
            string      bondLineName = "shape" + id;

            Int64Value width  = OoXmlHelper.ScaleCmlToEmu(cmlExtents.Width);
            Int64Value height = OoXmlHelper.ScaleCmlToEmu(cmlExtents.Height);
            Int64Value top    = OoXmlHelper.ScaleCmlToEmu(cmlExtents.Top);
            Int64Value left   = OoXmlHelper.ScaleCmlToEmu(cmlExtents.Left);

            Point location = new Point(left, top);
            Size  size     = new Size(width, height);

            location.Offset(OoXmlHelper.ScaleCmlToEmu(-m_canvasExtents.Left), OoXmlHelper.ScaleCmlToEmu(-m_canvasExtents.Top));
            Rect boundingBox = new Rect(location, size);

            width  = (Int64Value)boundingBox.Width;
            height = (Int64Value)boundingBox.Height;
            top    = (Int64Value)boundingBox.Top;
            left   = (Int64Value)boundingBox.Left;

            A.PresetGeometry presetGeometry = null;
            A.Extents        extents        = new A.Extents {
                Cx = width, Cy = height
            };
            presetGeometry = new A.PresetGeometry()
            {
                Preset = shape
            };

            Wps.WordprocessingShape        wordprocessingShape        = new Wps.WordprocessingShape();
            Wps.NonVisualDrawingProperties nonVisualDrawingProperties = new Wps.NonVisualDrawingProperties()
            {
                Id   = id,
                Name = bondLineName
            };

            Wps.NonVisualDrawingShapeProperties nonVisualDrawingShapeProperties = new Wps.NonVisualDrawingShapeProperties();

            Wps.ShapeProperties shapeProperties = new Wps.ShapeProperties();

            A.Transform2D transform2D = new A.Transform2D();
            A.Offset      offset      = new A.Offset {
                X = left, Y = top
            };

            transform2D.Append(offset);
            transform2D.Append(extents);

            A.AdjustValueList adjustValueList = new A.AdjustValueList();

            presetGeometry.Append(adjustValueList);
            A.SolidFill solidFill = new A.SolidFill();

            A.RgbColorModelHex rgbColorModelHex = new A.RgbColorModelHex {
                Val = colour
            };
            solidFill.Append(rgbColorModelHex);

            shapeProperties.Append(transform2D);
            shapeProperties.Append(presetGeometry);
            shapeProperties.Append(solidFill);

            OoXmlHelper.AppendShapeStyle(wordprocessingShape, nonVisualDrawingProperties, nonVisualDrawingShapeProperties, shapeProperties);
            wordprocessingGroup.Append(wordprocessingShape);
        }
Пример #2
0
        private void DrawDashedLine(Wpg.WordprocessingGroup wordprocessingGroup, Rect cmlExtents, Point bondStart, Point bondEnd, string colour = "000000")
        {
            UInt32Value id           = UInt32Value.FromUInt32((uint)m_ooxmlId++);
            string      bondLineName = "DashedBondLine" + id;

            Int64Value width  = OoXmlHelper.ScaleCmlToEmu(cmlExtents.Width);
            Int64Value height = OoXmlHelper.ScaleCmlToEmu(cmlExtents.Height);
            Int64Value top    = OoXmlHelper.ScaleCmlToEmu(cmlExtents.Top);
            Int64Value left   = OoXmlHelper.ScaleCmlToEmu(cmlExtents.Left);

            Wps.WordprocessingShape        shape = new Wps.WordprocessingShape();
            Wps.NonVisualDrawingProperties nonVisualDrawingProperties = new Wps.NonVisualDrawingProperties()
            {
                Id = id, Name = bondLineName
            };
            Wps.NonVisualDrawingShapeProperties nonVisualDrawingShapeProperties = new Wps.NonVisualDrawingShapeProperties();

            Wps.ShapeProperties shapeProperties = new Wps.ShapeProperties();

            A.Transform2D transform2D = new A.Transform2D();
            A.Offset      offset      = new A.Offset {
                X = left, Y = top
            };
            A.Extents extents = new A.Extents {
                Cx = width, Cy = height
            };

            transform2D.Append(offset);
            transform2D.Append(extents);

            A.CustomGeometry  customGeometry  = new A.CustomGeometry();
            A.AdjustValueList adjustValueList = new A.AdjustValueList();
            A.Rectangle       rectangle       = new A.Rectangle {
                Left = "l", Top = "t", Right = "r", Bottom = "b"
            };

            A.PathList pathList = new A.PathList();

            A.Path path = new A.Path {
                Width = width, Height = height
            };

            A.MoveTo moveTo = new A.MoveTo();
            A.Point  point1 = new A.Point {
                X = OoXmlHelper.ScaleCmlToEmu(bondStart.X).ToString(), Y = OoXmlHelper.ScaleCmlToEmu(bondStart.Y).ToString()
            };

            moveTo.Append(point1);

            A.LineTo lineTo = new A.LineTo();
            A.Point  point2 = new A.Point {
                X = OoXmlHelper.ScaleCmlToEmu(bondEnd.X).ToString(), Y = OoXmlHelper.ScaleCmlToEmu(bondEnd.Y).ToString()
            };

            lineTo.Append(point2);

            path.Append(moveTo);
            path.Append(lineTo);

            pathList.Append(path);

            customGeometry.Append(adjustValueList);
            customGeometry.Append(rectangle);
            customGeometry.Append(pathList);

            A.Outline outline = new A.Outline {
                Width = OoXmlHelper.ACS_LINE_WIDTH_EMUS, CapType = A.LineCapValues.Round
            };

            A.SolidFill  solidFill  = new A.SolidFill();
            A.PresetDash presetDash = new A.PresetDash()
            {
                Val = A.PresetLineDashValues.SystemDash
            };

            A.RgbColorModelHex rgbColorModelHex = new A.RgbColorModelHex {
                Val = colour
            };
            solidFill.Append(rgbColorModelHex);

            outline.Append(solidFill);
            outline.Append(presetDash);

            shapeProperties.Append(transform2D);
            shapeProperties.Append(customGeometry);
            shapeProperties.Append(outline);

            OoXmlHelper.AppendShapeStyle(shape, nonVisualDrawingProperties, nonVisualDrawingShapeProperties, shapeProperties);
            wordprocessingGroup.Append(shape);
        }
Пример #3
0
        private void DrawWedgeBond(Wpg.WordprocessingGroup wordprocessingGroup, List <Point> points)
        {
            UInt32Value id            = UInt32Value.FromUInt32((uint)m_ooxmlId++);
            string      atomLabelName = "WedgeBond" + id;

            Rect cmlExtents = new Rect(points[0], points[points.Count - 1]);

            for (int i = 0; i < points.Count - 1; i++)
            {
                cmlExtents.Union(new Rect(points[i], points[i + 1]));
            }

            // Move Extents to have 0,0 Top Left Reference
            cmlExtents.Offset(-m_canvasExtents.Left, -m_canvasExtents.Top);

            Int64Value top    = OoXmlHelper.ScaleCmlToEmu(cmlExtents.Y);
            Int64Value left   = OoXmlHelper.ScaleCmlToEmu(cmlExtents.X);
            Int64Value width  = OoXmlHelper.ScaleCmlToEmu(cmlExtents.Width);
            Int64Value height = OoXmlHelper.ScaleCmlToEmu(cmlExtents.Height);

            Wps.WordprocessingShape        shape = new Wps.WordprocessingShape();
            Wps.NonVisualDrawingProperties nonVisualDrawingProperties = new Wps.NonVisualDrawingProperties()
            {
                Id = id, Name = atomLabelName
            };
            Wps.NonVisualDrawingShapeProperties nonVisualDrawingShapeProperties = new Wps.NonVisualDrawingShapeProperties();

            Wps.ShapeProperties shapeProperties = new Wps.ShapeProperties();

            A.Transform2D transform2D = new A.Transform2D();
            A.Offset      offset      = new A.Offset {
                X = left, Y = top
            };
            A.Extents extents = new A.Extents {
                Cx = width, Cy = height
            };

            transform2D.Append(offset);
            transform2D.Append(extents);

            A.CustomGeometry  customGeometry  = new A.CustomGeometry();
            A.AdjustValueList adjustValueList = new A.AdjustValueList();
            A.Rectangle       rectangle       = new A.Rectangle {
                Left = "l", Top = "t", Right = "r", Bottom = "b"
            };

            A.PathList pathList = new A.PathList();

            A.Path path = new A.Path {
                Width = width, Height = height
            };

            A.MoveTo moveTo = new A.MoveTo();
            moveTo.Append(MakePoint(points[0]));
            path.Append(moveTo);

            for (int i = 1; i < points.Count; i++)
            {
                A.LineTo lineTo = new A.LineTo();
                lineTo.Append(MakePoint(points[i]));
                path.Append(lineTo);
            }

            A.CloseShapePath closeShapePath = new A.CloseShapePath();
            path.Append(closeShapePath);

            pathList.Append(path);

            customGeometry.Append(adjustValueList);
            customGeometry.Append(rectangle);
            customGeometry.Append(pathList);

            // Set shape fill colour
            A.SolidFill        solidFill1       = new A.SolidFill();
            A.RgbColorModelHex rgbColorModelHex = new A.RgbColorModelHex {
                Val = "000000"
            };
            solidFill1.Append(rgbColorModelHex);

            // Set shape outline colour
            A.Outline outline = new A.Outline {
                Width = OoXmlHelper.ACS_LINE_WIDTH_EMUS, CapType = A.LineCapValues.Round
            };
            A.RgbColorModelHex rgbColorModelHex2 = new A.RgbColorModelHex {
                Val = "000000"
            };
            A.SolidFill solidFill2 = new A.SolidFill();
            solidFill2.Append(rgbColorModelHex2);
            outline.Append(solidFill2);

            shapeProperties.Append(transform2D);
            shapeProperties.Append(customGeometry);
            shapeProperties.Append(solidFill1);
            shapeProperties.Append(outline);

            OoXmlHelper.AppendShapeStyle(shape, nonVisualDrawingProperties, nonVisualDrawingShapeProperties, shapeProperties);
            wordprocessingGroup.Append(shape);

            // Local Function
            A.Point MakePoint(Point pp)
            {
                pp.Offset(-m_canvasExtents.Left, -m_canvasExtents.Top);
                pp.Offset(-cmlExtents.Left, -cmlExtents.Top);
                return(new A.Point
                {
                    X = $"{OoXmlHelper.ScaleCmlToEmu(pp.X)}",
                    Y = $"{OoXmlHelper.ScaleCmlToEmu(pp.Y)}"
                });
            }
        }
Пример #4
0
        private void DrawWavyLine(Wpg.WordprocessingGroup wordprocessingGroup, Rect cmlExtents, Point bondStart, Point bondEnd)
        {
            UInt32Value id           = UInt32Value.FromUInt32((uint)m_ooxmlId++);
            string      bondLineName = "WavyLine" + id;

            Vector bondVector  = bondEnd - bondStart;
            int    noOfWiggles = (int)Math.Ceiling(bondVector.Length / BondOffset());

            if (noOfWiggles < 1)
            {
                noOfWiggles = 1;
            }

            double wiggleLength = bondVector.Length / noOfWiggles;

            Vector originalWigglePortion = bondVector;

            originalWigglePortion.Normalize();
            originalWigglePortion *= wiggleLength / 2;

            Matrix toLeft = new Matrix();

            toLeft.Rotate(-60);
            Matrix toRight = new Matrix();

            toRight.Rotate(60);
            Vector leftVector  = originalWigglePortion * toLeft;
            Vector rightVector = originalWigglePortion * toRight;

            List <Point>         allpoints    = new List <Point>();
            List <List <Point> > allTriangles = new List <List <Point> >();
            List <Point>         triangle     = new List <Point>();

            Point lastPoint = bondStart;

            allpoints.Add(lastPoint);
            triangle.Add(lastPoint);
            for (int i = 0; i < noOfWiggles; i++)
            {
                Point leftPoint = lastPoint + leftVector;
                allpoints.Add(leftPoint);
                triangle.Add(leftPoint);

                Point midPoint = lastPoint + originalWigglePortion;
                allpoints.Add(midPoint);
                triangle.Add(midPoint);
                allTriangles.Add(triangle);
                triangle = new List <Point>();
                triangle.Add(midPoint);

                Point rightPoint = lastPoint + originalWigglePortion + rightVector;
                allpoints.Add(rightPoint);
                triangle.Add(rightPoint);

                lastPoint += originalWigglePortion * 2;
                allpoints.Add(lastPoint);
                triangle.Add(lastPoint);
                allTriangles.Add(triangle);
                triangle = new List <Point>();
                triangle.Add(lastPoint);
            }

            double minX = double.MaxValue;
            double maxX = double.MinValue;
            double minY = double.MaxValue;
            double maxY = double.MinValue;

            foreach (Point p in allpoints)
            {
                maxX = Math.Max(p.X + cmlExtents.Left, maxX);
                minX = Math.Min(p.X + cmlExtents.Left, minX);
                maxY = Math.Max(p.Y + cmlExtents.Top, maxY);
                minY = Math.Min(p.Y + cmlExtents.Top, minY);
            }

            Rect   newExtents = new Rect(minX, minY, maxX - minX, maxY - minY);
            double xOffset    = cmlExtents.Left - newExtents.Left;
            double yOffset    = cmlExtents.Top - newExtents.Top;

            Int64Value width  = OoXmlHelper.ScaleCmlToEmu(newExtents.Width);
            Int64Value height = OoXmlHelper.ScaleCmlToEmu(newExtents.Height);
            Int64Value top    = OoXmlHelper.ScaleCmlToEmu(newExtents.Top);
            Int64Value left   = OoXmlHelper.ScaleCmlToEmu(newExtents.Left);

            Wps.WordprocessingShape        shape = new Wps.WordprocessingShape();
            Wps.NonVisualDrawingProperties nonVisualDrawingProperties = new Wps.NonVisualDrawingProperties()
            {
                Id = id, Name = bondLineName
            };
            Wps.NonVisualDrawingShapeProperties nonVisualDrawingShapeProperties = new Wps.NonVisualDrawingShapeProperties();

            Wps.ShapeProperties shapeProperties = new Wps.ShapeProperties();

            A.Transform2D transform2D = new A.Transform2D();
            A.Offset      offset      = new A.Offset {
                X = left, Y = top
            };
            A.Extents extents = new A.Extents {
                Cx = width, Cy = height
            };

            transform2D.Append(offset);
            transform2D.Append(extents);

            A.CustomGeometry  customGeometry  = new A.CustomGeometry();
            A.AdjustValueList adjustValueList = new A.AdjustValueList();
            A.Rectangle       rectangle       = new A.Rectangle {
                Left = "l", Top = "t", Right = "r", Bottom = "b"
            };

            A.PathList pathList = new A.PathList();

            A.Path path = new A.Path {
                Width = width, Height = height
            };

            A.MoveTo moveTo = new A.MoveTo();
            A.Point  point1 = new A.Point {
                X = OoXmlHelper.ScaleCmlToEmu(bondStart.X + xOffset).ToString(), Y = OoXmlHelper.ScaleCmlToEmu(bondStart.Y + yOffset).ToString()
            };
            moveTo.Append(point1);
            path.Append(moveTo);

            // Render as Curves
            foreach (var tri in allTriangles)
            {
                A.CubicBezierCurveTo cubicBezierCurveTo = new A.CubicBezierCurveTo();
                foreach (var p in tri)
                {
                    A.Point point = new A.Point {
                        X = OoXmlHelper.ScaleCmlToEmu(p.X + xOffset).ToString(), Y = OoXmlHelper.ScaleCmlToEmu(p.Y + yOffset).ToString()
                    };
                    cubicBezierCurveTo.Append(point);
                }
                path.Append(cubicBezierCurveTo);
            }

            // Render as Straight Lines
            //foreach (var p in allpoints)
            //{
            //    A.LineTo lineTo = new A.LineTo();
            //    A.Point point = new A.Point { X = OoXmlHelper.ScaleCmlToEmu(p.X + xOffset).ToString(), Y = OoXmlHelper.ScaleCmlToEmu(p.Y + yOffset).ToString() };
            //    lineTo.Append(point);
            //    path1.Append(lineTo);
            //}

            pathList.Append(path);

            customGeometry.Append(adjustValueList);
            customGeometry.Append(rectangle);
            customGeometry.Append(pathList);

            A.Outline outline = new A.Outline {
                Width = OoXmlHelper.ACS_LINE_WIDTH_EMUS, CapType = A.LineCapValues.Round
            };

            A.SolidFill solidFill = new A.SolidFill();

            A.RgbColorModelHex rgbColorModelHex = new A.RgbColorModelHex {
                Val = "000000"
            };
            solidFill.Append(rgbColorModelHex);

            outline.Append(solidFill);

            shapeProperties.Append(transform2D);
            shapeProperties.Append(customGeometry);
            shapeProperties.Append(outline);

            OoXmlHelper.AppendShapeStyle(shape, nonVisualDrawingProperties, nonVisualDrawingShapeProperties, shapeProperties);
            wordprocessingGroup.Append(shape);
        }
Пример #5
0
        public void DrawCharacter(Wpg.WordprocessingGroup wordprocessingGroup, AtomLabelCharacter alc)
        {
            Point characterPosition = new Point(alc.Position.X, alc.Position.Y);

            characterPosition.Offset(-_canvasExtents.Left, -_canvasExtents.Top);

            UInt32Value id            = UInt32Value.FromUInt32((uint)_ooxmlId++);
            string      atomLabelName = "Atom " + alc.ParentAtom;

            Int64Value width  = OoXmlHelper.ScaleCsTtfToEmu(alc.Character.Width, _meanBondLength);
            Int64Value height = OoXmlHelper.ScaleCsTtfToEmu(alc.Character.Height, _meanBondLength);

            if (alc.IsSmaller)
            {
                width  = OoXmlHelper.ScaleCsTtfSubScriptToEmu(alc.Character.Width, _meanBondLength);
                height = OoXmlHelper.ScaleCsTtfSubScriptToEmu(alc.Character.Height, _meanBondLength);
            }
            Int64Value top  = OoXmlHelper.ScaleCmlToEmu(characterPosition.Y);
            Int64Value left = OoXmlHelper.ScaleCmlToEmu(characterPosition.X);

            // Set variable true to show bounding box of (every) character
            if (_options.ShowCharacterBoundingBoxes)
            {
                Rect boundingBox = new Rect(new Point(left, top), new Size(width, height));
                DrawCharacterBox(wordprocessingGroup, boundingBox, "00ff00", 0.25);
            }

            Wps.WordprocessingShape        shape = new Wps.WordprocessingShape();
            Wps.NonVisualDrawingProperties nonVisualDrawingProperties = new Wps.NonVisualDrawingProperties()
            {
                Id = id, Name = atomLabelName
            };
            Wps.NonVisualDrawingShapeProperties nonVisualDrawingShapeProperties = new Wps.NonVisualDrawingShapeProperties();

            Wps.ShapeProperties shapeProperties = new Wps.ShapeProperties();

            A.Transform2D transform2D = new A.Transform2D();
            A.Offset      offset      = new A.Offset {
                X = left, Y = top
            };
            A.Extents extents = new A.Extents {
                Cx = width, Cy = height
            };

            transform2D.Append(offset);
            transform2D.Append(extents);

            A.CustomGeometry  geometry        = new A.CustomGeometry();
            A.AdjustValueList adjustValueList = new A.AdjustValueList();
            A.Rectangle       rectangle       = new A.Rectangle {
                Left = "l", Top = "t", Right = "r", Bottom = "b"
            };

            A.PathList pathList = new A.PathList();

            A.Path path = new A.Path {
                Width = width, Height = height
            };

            foreach (TtfContour contour in alc.Character.Contours)
            {
                int i = 0;

                while (i < contour.Points.Count)
                {
                    TtfPoint thisPoint = contour.Points[i];
                    TtfPoint nextPoint = null;
                    if (i < contour.Points.Count - 1)
                    {
                        nextPoint = contour.Points[i + 1];
                    }

                    switch (thisPoint.Type)
                    {
                    case TtfPoint.PointType.Start:
                        A.MoveTo moveTo = new A.MoveTo();
                        if (alc.IsSmaller)
                        {
                            A.Point point = MakeSubscriptPoint(thisPoint);
                            moveTo.Append(point);
                            path.Append(moveTo);
                        }
                        else
                        {
                            A.Point point = MakeNormalPoint(thisPoint);
                            moveTo.Append(point);
                            path.Append(moveTo);
                        }
                        i++;
                        break;

                    case TtfPoint.PointType.Line:
                        A.LineTo lineTo = new A.LineTo();
                        if (alc.IsSmaller)
                        {
                            A.Point point = MakeSubscriptPoint(thisPoint);
                            lineTo.Append(point);
                            path.Append(lineTo);
                        }
                        else
                        {
                            A.Point point = MakeNormalPoint(thisPoint);
                            lineTo.Append(point);
                            path.Append(lineTo);
                        }
                        i++;
                        break;

                    case TtfPoint.PointType.CurveOff:
                        A.QuadraticBezierCurveTo quadraticBezierCurveTo = new A.QuadraticBezierCurveTo();
                        if (alc.IsSmaller)
                        {
                            A.Point pointA = MakeSubscriptPoint(thisPoint);
                            A.Point pointB = MakeSubscriptPoint(nextPoint);
                            quadraticBezierCurveTo.Append(pointA);
                            quadraticBezierCurveTo.Append(pointB);
                            path.Append(quadraticBezierCurveTo);
                        }
                        else
                        {
                            A.Point pointA = MakeNormalPoint(thisPoint);
                            A.Point pointB = MakeNormalPoint(nextPoint);
                            quadraticBezierCurveTo.Append(pointA);
                            quadraticBezierCurveTo.Append(pointB);
                            path.Append(quadraticBezierCurveTo);
                        }
                        i++;
                        i++;
                        break;

                    case TtfPoint.PointType.CurveOn:
                        // Should never get here !
                        i++;
                        break;
                    }
                }

                A.CloseShapePath closeShapePath = new A.CloseShapePath();
                path.Append(closeShapePath);
            }

            pathList.Append(path);

            geometry.Append(adjustValueList);
            geometry.Append(rectangle);
            geometry.Append(pathList);

            A.SolidFill solidFill = new A.SolidFill();

            // Set Colour
            A.RgbColorModelHex rgbColorModelHex = new A.RgbColorModelHex {
                Val = alc.Colour
            };
            solidFill.Append(rgbColorModelHex);

            shapeProperties.Append(transform2D);
            shapeProperties.Append(geometry);
            shapeProperties.Append(solidFill);

            OoXmlHelper.AppendShapeStyle(shape, nonVisualDrawingProperties, nonVisualDrawingShapeProperties, shapeProperties);
            wordprocessingGroup.Append(shape);

            // Local Functions
            A.Point MakeSubscriptPoint(TtfPoint ttfPoint)
            {
                A.Point pp = new A.Point
                {
                    X = $"{OoXmlHelper.ScaleCsTtfSubScriptToEmu(ttfPoint.X - alc.Character.OriginX, _meanBondLength)}",
                    Y = $"{OoXmlHelper.ScaleCsTtfSubScriptToEmu(alc.Character.Height + ttfPoint.Y - (alc.Character.Height + alc.Character.OriginY), _meanBondLength)}"
                };
                return(pp);
            }

            A.Point MakeNormalPoint(TtfPoint ttfPoint)
            {
                A.Point pp = new A.Point
                {
                    X = $"{OoXmlHelper.ScaleCsTtfToEmu(ttfPoint.X - alc.Character.OriginX, _meanBondLength)}",
                    Y = $"{OoXmlHelper.ScaleCsTtfToEmu(alc.Character.Height + ttfPoint.Y - (alc.Character.Height + alc.Character.OriginY), _meanBondLength)}"
                };
                return(pp);
            }
        }
Пример #6
0
        private void DrawCharacterBox(Wpg.WordprocessingGroup wordprocessingGroup, Rect boxExtents, string colour, double points)
        {
            UInt32Value id           = UInt32Value.FromUInt32((uint)_ooxmlId++);
            string      bondLineName = "char-diag-box-" + id;

            Int64Value width  = (Int64Value)boxExtents.Width;
            Int64Value height = (Int64Value)boxExtents.Height;
            Int64Value top    = (Int64Value)boxExtents.Top;
            Int64Value left   = (Int64Value)boxExtents.Left;

            Wps.WordprocessingShape        shape = new Wps.WordprocessingShape();
            Wps.NonVisualDrawingProperties nonVisualDrawingProperties = new Wps.NonVisualDrawingProperties()
            {
                Id   = id,
                Name = bondLineName
            };
            Wps.NonVisualDrawingShapeProperties nonVisualDrawingShapeProperties = new Wps.NonVisualDrawingShapeProperties();

            Wps.ShapeProperties shapeProperties = new Wps.ShapeProperties();

            A.Transform2D transform2D = new A.Transform2D();
            A.Offset      offset      = new A.Offset {
                X = left, Y = top
            };
            A.Extents extents = new A.Extents {
                Cx = width, Cy = height
            };

            transform2D.Append(offset);
            transform2D.Append(extents);

            A.CustomGeometry  customGeometry  = new A.CustomGeometry();
            A.AdjustValueList adjustValueList = new A.AdjustValueList();
            A.Rectangle       rectangle       = new A.Rectangle {
                Left = "l", Top = "t", Right = "r", Bottom = "b"
            };

            A.PathList pathList = new A.PathList();

            A.Path path = new A.Path {
                Width = width, Height = height
            };

            // Starting Point
            A.MoveTo moveTo = new A.MoveTo();
            A.Point  point1 = new A.Point {
                X = "0", Y = "0"
            };
            moveTo.Append(point1);

            // Mid Point
            A.LineTo lineTo1 = new A.LineTo();
            A.Point  point2  = new A.Point {
                X = boxExtents.Width.ToString("0"), Y = "0"
            };
            lineTo1.Append(point2);

            // Mid Point
            A.LineTo lineTo2 = new A.LineTo();
            A.Point  point3  = new A.Point {
                X = boxExtents.Width.ToString("0"), Y = boxExtents.Height.ToString("0")
            };
            lineTo2.Append(point3);

            // Last Point
            A.LineTo lineTo3 = new A.LineTo();
            A.Point  point4  = new A.Point {
                X = "0", Y = boxExtents.Height.ToString("0")
            };
            lineTo3.Append(point4);

            // Back to Start Point
            A.LineTo lineTo4 = new A.LineTo();
            A.Point  point5  = new A.Point {
                X = "0", Y = "0"
            };
            lineTo4.Append(point5);

            path.Append(moveTo);
            path.Append(lineTo1);
            path.Append(lineTo2);
            path.Append(lineTo3);
            path.Append(lineTo4);

            pathList.Append(path);

            customGeometry.Append(adjustValueList);
            customGeometry.Append(rectangle);
            customGeometry.Append(pathList);

            Int32Value emus = (Int32Value)(points * OoXmlHelper.EMUS_PER_WORD_POINT);

            A.Outline outline = new A.Outline {
                Width = emus, CapType = A.LineCapValues.Round
            };

            A.SolidFill solidFill = new A.SolidFill();

            A.RgbColorModelHex rgbColorModelHex = new A.RgbColorModelHex {
                Val = colour
            };
            solidFill.Append(rgbColorModelHex);

            outline.Append(solidFill);

            shapeProperties.Append(transform2D);
            shapeProperties.Append(customGeometry);
            shapeProperties.Append(outline);

            OoXmlHelper.AppendShapeStyle(shape, nonVisualDrawingProperties, nonVisualDrawingShapeProperties, shapeProperties);
            wordprocessingGroup.Append(shape);
        }