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);
            }
        }
        public void DrawCharacter(Wpg.WordprocessingGroup wordprocessingGroup1, AtomLabelCharacter alc)
        {
            Point characterPosition = new Point(alc.Position.X, alc.Position.Y);

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

            UInt32Value atomLabelId   = UInt32Value.FromUInt32((uint)_ooxmlId++);
            string      atomLabelName = "AtomLabel" + atomLabelId;

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

            if (alc.IsSubScript)
            {
                width  = OoXmlHelper.ScaleCsTtfSubScriptToEmu(alc.Character.Width);
                height = OoXmlHelper.ScaleCsTtfSubScriptToEmu(alc.Character.Height);
            }
            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(wordprocessingGroup1, boundingBox, "00ff00", 10);
            }

            Wps.WordprocessingShape        wordprocessingShape10        = new Wps.WordprocessingShape();
            Wps.NonVisualDrawingProperties nonVisualDrawingProperties10 = new Wps.NonVisualDrawingProperties()
            {
                Id = atomLabelId, Name = atomLabelName
            };
            Wps.NonVisualDrawingShapeProperties nonVisualDrawingShapeProperties10 = new Wps.NonVisualDrawingShapeProperties();

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

            A.Transform2D transform2D10 = new A.Transform2D();
            A.Offset      offset11      = new A.Offset()
            {
                X = left, Y = top
            };
            A.Extents extents11 = new A.Extents()
            {
                Cx = width, Cy = height
            };

            transform2D10.Append(offset11);
            transform2D10.Append(extents11);

            A.CustomGeometry  customGeometry10  = new A.CustomGeometry();
            A.AdjustValueList adjustValueList10 = new A.AdjustValueList();
            A.Rectangle       rectangle10       = new A.Rectangle()
            {
                Left = "l", Top = "t", Right = "r", Bottom = "b"
            };

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

            A.Path path10 = 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 moveTo1 = new A.MoveTo();
                        if (alc.IsSubScript)
                        {
                            A.Point point1 = new A.Point()
                            {
                                X = OoXmlHelper.ScaleCsTtfSubScriptToEmu(thisPoint.X - alc.Character.OriginX).ToString(),
                                Y = OoXmlHelper.ScaleCsTtfSubScriptToEmu(alc.Character.Height + thisPoint.Y - (alc.Character.Height + alc.Character.OriginY)).ToString()
                            };
                            moveTo1.Append(point1);
                            path10.Append(moveTo1);
                        }
                        else
                        {
                            A.Point point1 = new A.Point()
                            {
                                X = OoXmlHelper.ScaleCsTtfToEmu(thisPoint.X - alc.Character.OriginX).ToString(),
                                Y = OoXmlHelper.ScaleCsTtfToEmu(alc.Character.Height + thisPoint.Y - (alc.Character.Height + alc.Character.OriginY)).ToString()
                            };
                            moveTo1.Append(point1);
                            path10.Append(moveTo1);
                        }
                        i++;
                        break;

                    case TtfPoint.PointType.Line:
                        A.LineTo lineTo1 = new A.LineTo();
                        if (alc.IsSubScript)
                        {
                            A.Point point2 = new A.Point()
                            {
                                X = OoXmlHelper.ScaleCsTtfSubScriptToEmu(thisPoint.X - alc.Character.OriginX).ToString(),
                                Y = OoXmlHelper.ScaleCsTtfSubScriptToEmu(alc.Character.Height + thisPoint.Y - (alc.Character.Height + alc.Character.OriginY)).ToString()
                            };
                            lineTo1.Append(point2);
                            path10.Append(lineTo1);
                        }
                        else
                        {
                            A.Point point2 = new A.Point()
                            {
                                X = OoXmlHelper.ScaleCsTtfToEmu(thisPoint.X - alc.Character.OriginX).ToString(),
                                Y = OoXmlHelper.ScaleCsTtfToEmu(alc.Character.Height + thisPoint.Y - (alc.Character.Height + alc.Character.OriginY)).ToString()
                            };
                            lineTo1.Append(point2);
                            path10.Append(lineTo1);
                        }
                        i++;
                        break;

                    case TtfPoint.PointType.CurveOff:
                        A.QuadraticBezierCurveTo quadraticBezierCurveTo13 = new A.QuadraticBezierCurveTo();
                        if (alc.IsSubScript)
                        {
                            A.Point point3 = new A.Point()
                            {
                                X = OoXmlHelper.ScaleCsTtfSubScriptToEmu(thisPoint.X - alc.Character.OriginX).ToString(),
                                Y = OoXmlHelper.ScaleCsTtfSubScriptToEmu(alc.Character.Height + thisPoint.Y - (alc.Character.Height + alc.Character.OriginY)).ToString()
                            };
                            A.Point point4 = new A.Point()
                            {
                                X = OoXmlHelper.ScaleCsTtfSubScriptToEmu(nextPoint.X - alc.Character.OriginX).ToString(),
                                Y = OoXmlHelper.ScaleCsTtfSubScriptToEmu(alc.Character.Height + nextPoint.Y - (alc.Character.Height + alc.Character.OriginY)).ToString()
                            };
                            quadraticBezierCurveTo13.Append(point3);
                            quadraticBezierCurveTo13.Append(point4);
                            path10.Append(quadraticBezierCurveTo13);
                        }
                        else
                        {
                            A.Point point3 = new A.Point()
                            {
                                X = OoXmlHelper.ScaleCsTtfToEmu(thisPoint.X - alc.Character.OriginX).ToString(),
                                Y = OoXmlHelper.ScaleCsTtfToEmu(alc.Character.Height + thisPoint.Y - (alc.Character.Height + alc.Character.OriginY)).ToString()
                            };
                            A.Point point4 = new A.Point()
                            {
                                X = OoXmlHelper.ScaleCsTtfToEmu(nextPoint.X - alc.Character.OriginX).ToString(),
                                Y = OoXmlHelper.ScaleCsTtfToEmu(alc.Character.Height + nextPoint.Y - (alc.Character.Height + alc.Character.OriginY)).ToString()
                            };
                            quadraticBezierCurveTo13.Append(point3);
                            quadraticBezierCurveTo13.Append(point4);
                            path10.Append(quadraticBezierCurveTo13);
                        }
                        i++;
                        i++;
                        break;

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

                A.CloseShapePath closeShapePath1 = new A.CloseShapePath();
                path10.Append(closeShapePath1);
            }

            pathList10.Append(path10);

            customGeometry10.Append(adjustValueList10);
            customGeometry10.Append(rectangle10);
            customGeometry10.Append(pathList10);

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

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

            shapeProperties10.Append(transform2D10);
            shapeProperties10.Append(customGeometry10);
            shapeProperties10.Append(solidFill10);

            Wps.ShapeStyle  shapeStyle10    = new Wps.ShapeStyle();
            A.LineReference lineReference10 = new A.LineReference()
            {
                Index = (UInt32Value)0U
            };
            A.FillReference fillReference10 = new A.FillReference()
            {
                Index = (UInt32Value)0U
            };
            A.EffectReference effectReference10 = new A.EffectReference()
            {
                Index = (UInt32Value)0U
            };
            A.FontReference fontReference10 = new A.FontReference()
            {
                Index = A.FontCollectionIndexValues.Minor
            };

            shapeStyle10.Append(lineReference10);
            shapeStyle10.Append(fillReference10);
            shapeStyle10.Append(effectReference10);
            shapeStyle10.Append(fontReference10);
            Wps.TextBodyProperties textBodyProperties10 = new Wps.TextBodyProperties();

            wordprocessingShape10.Append(nonVisualDrawingProperties10);
            wordprocessingShape10.Append(nonVisualDrawingShapeProperties10);
            wordprocessingShape10.Append(shapeProperties10);
            wordprocessingShape10.Append(shapeStyle10);
            wordprocessingShape10.Append(textBodyProperties10);

            wordprocessingGroup1.Append(wordprocessingShape10);
        }