Kaynağa Gözat

处理公式

CrazyIter 4 yıl önce
ebeveyn
işleme
07191cb7fb

+ 3 - 3
HTEXLib/Builders/HtexBuilder.cs

@@ -82,8 +82,8 @@ namespace HTEXLib.Builders
                 throw new ArgumentNullException("Presentation Document missing");
             }
             IEnumerable<SlideMasterPart> slideMasterParts= presentationDocument.PresentationPart.SlideMasterParts;///用于获取PPT母版背景
-         
-            IEnumerable<SlidePart> slideParts = GetPresentationSlideParts(presentationDocument);
+           
+               IEnumerable<SlidePart> slideParts = GetPresentationSlideParts(presentationDocument);
             preserveWhitespaces(slideParts);//bug fix; whitespaces in separate runs are not preserved
             List<PPTSlide> pptSlides = GetPPTSlidesFromParts(slideParts, presentationDocument.PresentationPart.Presentation.DefaultTextStyle, presentationDocument.PresentationPart.SlideMasterParts, presentationDocument);
           
@@ -136,7 +136,7 @@ namespace HTEXLib.Builders
                 {
                     pptSlides[pptSlides.Count - 1].advanceAfterTime = int.Parse(slidePart.Slide.Transition.AdvanceAfterTime.Value);
                 }
-                var pptSlide = new PPTSlide(slidePart, slideIndex, defaultTextStyle,  SlideSizes, slideMaster, root,media);
+                var pptSlide = new PPTSlide(slidePart, slideIndex, defaultTextStyle,  SlideSizes, slideMaster, root,media, presentationDocument.PresentationPart.TableStylesPart);
                 pptSlides.Add(pptSlide);
                 slideIndex++;
             }

Dosya farkı çok büyük olduğundan ihmal edildi
+ 118 - 20
HTEXLib/Builders/PPTContainerShapeBuilder.cs


+ 57 - 6
HTEXLib/Helpers/ColorHelpers/ColorConverter.cs

@@ -122,6 +122,15 @@ namespace HTEXLib
             }
            
         }
+        internal string SetComp(string colorHex)
+        {
+            Color c = ColorTranslator.FromHtml("#" + colorHex);
+            int cc = Max(c) + Min(c);
+            var rn = cc - c.R;
+            var gn = cc - c.G;
+            var bn = cc - c.B;
+            return rn.ToString("X2") + gn.ToString("X2") + bn.ToString("X2");
+        }
         private double RGB_to_linearRGB(double val)
         {
 
@@ -295,14 +304,56 @@ namespace HTEXLib
             return outColor.R.ToString("X2") + outColor.G.ToString("X2") + outColor.B.ToString("X2");
         }
 
-        internal string SetComp(string colorHex)
+        public byte Max(byte r, byte g, byte b) {
+            byte max = r;
+            if (max < g) {
+                max = g;
+            }
+            if (max < b) {
+                max = b;
+            }
+            return max;
+        }
+        public byte Min(byte r, byte g, byte b)
         {
-            Color c = ColorTranslator.FromHtml("#" + colorHex);
-            var rn = 255 - c.R;
-            var gn = 255 - c.G;
-            var bn = 255 - c.B;
-            return rn.ToString("X2") + gn.ToString("X2") +bn.ToString("X2");
+            byte min = r;
+            if (min > g)
+            {
+                min = g;
+            }
+            if (min > b)
+            {
+                min = b;
+            }
+            return min;
+        }
+        public byte Max(Color color)
+        {
+            byte max = color.R;
+            if (max < color.G)
+            {
+                max = color.G;
+            }
+            if (max < color.B)
+            {
+                max = color.B;
+            }
+            return max;
+        }
+        public byte Min(Color color)
+        {
+            byte min = color.R;
+            if (min > color.G)
+            {
+                min = color.G;
+            }
+            if (min > color.B)
+            {
+                min = color.B;
+            }
+            return min;
         }
+        
 
         public string SetHueMod(Color c, double hue)
         {

+ 382 - 57
HTEXLib/Helpers/ShapeHelpers/PPTXHelper.cs

@@ -11,6 +11,7 @@ using HTEXLib.Models;
 using ColorType = DocumentFormat.OpenXml.Drawing.ColorType;
 using System.Linq;
 using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Drawing.Charts;
 
 namespace HTEXLib.Helpers.ShapeHelpers
 {
@@ -64,6 +65,116 @@ namespace HTEXLib.Helpers.ShapeHelpers
             string FontColor = FontReferenceColors(shapeStyle.FontReference, slide);
             return new SlideColor { LineColor = LineColor, FillColor = FillColor, EffectColor = EffectColor, FontColor = FontColor };
         }
+        public static HTEXLib.Models.HTEX.ShapeStyle DoShapeProperties(DocumentFormat.OpenXml.Drawing.Charts.ShapeProperties shapeProperties, PPTSlide slide, string type, string partForm)
+        {
+            //Outline
+            var lnNode = shapeProperties.GetFirstChild<Outline>();
+            Border border = null;
+            if (lnNode != null)
+            {
+                border = DoOutline(lnNode, slide, type);
+            }
+            Fill fill = new Fill() { type = -1 };
+            var gradFill = shapeProperties.GetFirstChild<GradientFill>();
+            if (gradFill != null)
+            {
+                fill.type = 2;
+                fill.gradientFill = DoGradientFill(gradFill, slide);
+            }
+            var noFill = shapeProperties.GetFirstChild<NoFill>();
+            if (noFill != null)
+            {
+                fill.type = 0;
+            }
+            var pattFill = shapeProperties.GetFirstChild<PatternFill>();
+            if (pattFill != null)
+            {
+                HtexPattFill htexPattFill = DoPattFill(pattFill, slide);
+                fill.type = 4;
+                fill.pattFill = htexPattFill;
+            }
+            var solidFill = shapeProperties.GetFirstChild<SolidFill>();
+            if (solidFill != null)
+            {
+                fill.type = 1;
+                fill.solidFill = DoSolidFill(solidFill, slide);
+            }
+            var groupFill = shapeProperties.GetFirstChild<GroupFill>();
+            if (groupFill != null)
+            {
+                fill.type = 5;
+                //  fill.solidFill = ReadSolidFillColors(new SolidFill(solidFill.ToString()), slide);
+            }
+            var blipFill = shapeProperties.GetFirstChild<DocumentFormat.OpenXml.Drawing.BlipFill>();
+            if (blipFill != null)
+            {
+                fill.type = 3;
+                fill.blipFill = DoBlipFill(blipFill, slide, partForm);
+                //  fill.solidFill = ReadSolidFillColors(new SolidFill(solidFill.ToString()), slide);
+            }
+            var EffectList = shapeProperties.GetFirstChild<EffectList>();
+            var EffectDag = shapeProperties.GetFirstChild<EffectDag>();
+            var Scene3DType = shapeProperties.GetFirstChild<Scene3DType>();
+            var Shape3DType = shapeProperties.GetFirstChild<Shape3DType>();
+            var ShapePropertiesExtensionList = shapeProperties.GetFirstChild<ShapePropertiesExtensionList>();
+            // CustomGeometry PresetGeometry  TODO
+            return new HTEXLib.Models.HTEX.ShapeStyle { fill = fill, border = border };
+        }
+        public static HTEXLib.Models.HTEX.ShapeStyle DoShapeProperties(ChartShapeProperties shapeProperties, PPTSlide slide, string type, string partForm)
+        {
+            //Outline
+            var lnNode = shapeProperties.GetFirstChild<Outline>();
+            Border border = null;
+            if (lnNode != null)
+            {
+                border = DoOutline(lnNode, slide, type);
+            }
+            Fill fill = new Fill() { type = -1 };
+            var gradFill = shapeProperties.GetFirstChild<GradientFill>();
+            if (gradFill != null)
+            {
+                fill.type = 2;
+                fill.gradientFill = DoGradientFill(gradFill, slide);
+            }
+            var noFill = shapeProperties.GetFirstChild<NoFill>();
+            if (noFill != null)
+            {
+                fill.type = 0;
+            }
+            var pattFill = shapeProperties.GetFirstChild<PatternFill>();
+            if (pattFill != null)
+            {
+                HtexPattFill htexPattFill = DoPattFill(pattFill, slide);
+                fill.type = 4;
+                fill.pattFill = htexPattFill;
+            }
+            var solidFill = shapeProperties.GetFirstChild<SolidFill>();
+            if (solidFill != null)
+            {
+                fill.type = 1;
+                fill.solidFill = DoSolidFill(solidFill, slide);
+            }
+            var groupFill = shapeProperties.GetFirstChild<GroupFill>();
+            if (groupFill != null)
+            {
+                fill.type = 5;
+                //  fill.solidFill = ReadSolidFillColors(new SolidFill(solidFill.ToString()), slide);
+            }
+            var blipFill = shapeProperties.GetFirstChild<DocumentFormat.OpenXml.Drawing.BlipFill>();
+            if (blipFill != null)
+            {
+                fill.type = 3;
+                fill.blipFill = DoBlipFill(blipFill, slide, partForm);
+                //  fill.solidFill = ReadSolidFillColors(new SolidFill(solidFill.ToString()), slide);
+            }
+            var EffectList = shapeProperties.GetFirstChild<EffectList>();
+            var EffectDag = shapeProperties.GetFirstChild<EffectDag>();
+            var Scene3DType = shapeProperties.GetFirstChild<Scene3DType>();
+            var Shape3DType = shapeProperties.GetFirstChild<Shape3DType>();
+            var ShapePropertiesExtensionList = shapeProperties.GetFirstChild<ShapePropertiesExtensionList>();
+            // CustomGeometry PresetGeometry  TODO
+            return new HTEXLib.Models.HTEX.ShapeStyle { fill = fill, border = border };
+        }
         public static HTEXLib.Models.HTEX.ShapeStyle DoShapeProperties(GroupShapeProperties shapeProperties, PPTSlide slide, string type, string partForm)
         {
             //Outline
@@ -118,7 +229,7 @@ namespace HTEXLib.Helpers.ShapeHelpers
             var ShapePropertiesExtensionList = shapeProperties.GetFirstChild<ShapePropertiesExtensionList>();
             return new HTEXLib.Models.HTEX.ShapeStyle { fill = fill, border = border };
         }
-        public static HTEXLib.Models.HTEX.ShapeStyle DoTableProperties(TableProperties shapeProperties, PPTSlide slide, string type, string partForm)
+        public static TbStyle DoTableProperties(TableProperties shapeProperties, PPTSlide slide, string type, string partForm)
         {
             Fill fill = new Fill() { type = -1 };
             var gradFill = shapeProperties.GetFirstChild<GradientFill>();
@@ -158,97 +269,178 @@ namespace HTEXLib.Helpers.ShapeHelpers
                 fill.blipFill = DoBlipFill(blipFill, slide, partForm);
                 //  fill.solidFill = ReadSolidFillColors(new SolidFill(solidFill.ToString()), slide);
             }
+            var TableStyleId = shapeProperties.GetFirstChild<TableStyleId>().InnerText;
+            TableStyleType TableStyle = shapeProperties.GetFirstChild<TableStyle>();
+            if (TableStyle == null)
+            {
+               var TableStyleEntrys = slide.tableStylesPart.TableStyleList.Elements<TableStyleEntry>();
+                foreach (var TableStyleEntry in TableStyleEntrys) {
+                    if (TableStyleEntry.StyleId == TableStyleId) {
+                        TableStyle = TableStyleEntry;
+                    }
+                }
+            }
+            TbStyle tbStyle =DoTableStyle(TableStyle,slide,type,partForm);
+            if (fill != null &&  fill.type == -1)
+            {
+                tbStyle.fill = fill;
+            }
+            //TODO
             var EffectList = shapeProperties.GetFirstChild<EffectList>();
             var EffectDag = shapeProperties.GetFirstChild<EffectDag>();
-            var TableStyle = shapeProperties.GetFirstChild<TableStyle>();
-
-            var TableStyleId = shapeProperties.GetFirstChild<TableStyleId>();
             var ShapePropertiesExtensionList = shapeProperties.GetFirstChild<DocumentFormat.OpenXml.Drawing.ExtensionList>();
-
-            return new HTEXLib.Models.HTEX.ShapeStyle { fill = fill};
+            tbStyle.RightToLeft = shapeProperties.RightToLeft != null? shapeProperties.RightToLeft.Value:false;
+            tbStyle.FirstRow = shapeProperties.FirstRow != null ? shapeProperties.FirstRow.Value : false;
+            tbStyle.FirstColumn = shapeProperties.FirstColumn != null ? shapeProperties.FirstColumn.Value : false;
+            tbStyle.LastRow = shapeProperties.LastRow != null ? shapeProperties.LastRow.Value : false;
+            tbStyle.LastColumn = shapeProperties.LastColumn != null ? shapeProperties.LastColumn.Value : false;
+            tbStyle.BandRow = shapeProperties.BandRow != null ? shapeProperties.BandRow.Value : false;
+            tbStyle.BandColumn = shapeProperties.BandColumn != null ? shapeProperties.BandColumn.Value : false;
+            return tbStyle;
         }
 
-        public static void DoTableStyle(TableStyle tableStyle, PPTSlide slide, string type, string partForm) {
+        public static TbStyle DoTableStyle(TableStyleType tableStyle, PPTSlide slide, string type, string partForm) {
+            TbStyle tbStyle = new TbStyle();
+            if (tableStyle == null) {
+                return tbStyle;
+            }
             var TableBackground = tableStyle.TableBackground;
             if (TableBackground != null)
             {
                 var shapeProperties = TableBackground.GetFirstChild<FillProperties>();
                 Fill fill = DoFillProperties(shapeProperties , partForm,slide );
                 var FillReference = TableBackground.GetFirstChild<FillReference>();
-                DoFillReference(slide, fill, FillReference);
+                fill=  DoFillReference(slide, fill, FillReference);
+                tbStyle.fill = fill;
                 //TODO
                 TableBackground.GetFirstChild<EffectPropertiesType>();
                 TableBackground.GetFirstChild<EffectReference>();
             }
             //TablePartStyleType
+
+            List<CellStyle> cellStyles = new List<CellStyle>();
+
             var WholeTable = tableStyle.WholeTable;
             if (WholeTable != null) {
-                DoTablePartStyleType(WholeTable, slide, type, partForm);
+                var style= DoTablePartStyleType(WholeTable, slide, type, partForm);
+                if (style != null) {
+                    cellStyles.Add(style);
+                }
             }
             var Band1Horizontal = tableStyle.Band1Horizontal;
             if (Band1Horizontal != null)
             {
-                DoTablePartStyleType(Band1Horizontal, slide, type, partForm);
+                var style= DoTablePartStyleType(Band1Horizontal, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
             var Band2Horizontal = tableStyle.Band2Horizontal;
             if (Band2Horizontal != null)
             {
-                DoTablePartStyleType(Band2Horizontal, slide, type, partForm);
+                var style= DoTablePartStyleType(Band2Horizontal, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
             var Band1Vertical = tableStyle.Band1Vertical;
             if (Band1Vertical != null)
             {
-                DoTablePartStyleType(Band1Vertical, slide, type, partForm);
+                var style= DoTablePartStyleType(Band1Vertical, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
             var Band2Vertical = tableStyle.Band2Vertical;
             if (Band2Vertical != null)
             {
-                DoTablePartStyleType(Band2Vertical, slide, type, partForm);
+                var style= DoTablePartStyleType(Band2Vertical, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
             var LastColumn = tableStyle.LastColumn;
             if (LastColumn != null)
             {
-                DoTablePartStyleType(LastColumn, slide, type, partForm);
+                var style= DoTablePartStyleType(LastColumn, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
             var FirstColumn = tableStyle.FirstColumn;
             if (FirstColumn != null)
             {
-                DoTablePartStyleType(FirstColumn, slide, type, partForm);
+                var style= DoTablePartStyleType(FirstColumn, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
             var FirstRow = tableStyle.FirstRow;
             if (FirstRow != null)
             {
-                DoTablePartStyleType(FirstRow, slide, type, partForm);
+                var style= DoTablePartStyleType(FirstRow, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
             var LastRow = tableStyle.LastRow;
             if (LastRow != null)
             {
-                DoTablePartStyleType(LastRow, slide, type, partForm);
+                var style= DoTablePartStyleType(LastRow, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
             var SoutheastCell = tableStyle.SoutheastCell;
             if (SoutheastCell != null)
             {
-                DoTablePartStyleType(SoutheastCell, slide, type, partForm);
+                var style= DoTablePartStyleType(SoutheastCell, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
             var SouthwestCell = tableStyle.SouthwestCell;
             if (SouthwestCell != null)
             {
-                DoTablePartStyleType(SouthwestCell, slide, type, partForm);
+                var style= DoTablePartStyleType(SouthwestCell, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
             var NortheastCell = tableStyle.NortheastCell;
             if (NortheastCell != null)
             {
-                DoTablePartStyleType(NortheastCell, slide, type, partForm);
+                var style= DoTablePartStyleType(NortheastCell, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
             var NorthwestCell = tableStyle.NorthwestCell;
             if (NorthwestCell != null)
             {
-                DoTablePartStyleType(NorthwestCell, slide, type, partForm);
+                var style= DoTablePartStyleType(NorthwestCell, slide, type, partForm);
+                if (style != null)
+                {
+                    cellStyles.Add(style);
+                }
             }
+            tbStyle.cellStyles = cellStyles;
             var ExtensionList = tableStyle.ExtensionList;
+            return tbStyle;
         }
 
-        private static void DoFillReference(PPTSlide slide, Fill fill, FillReference FillReference)
+        private static Fill   DoFillReference(PPTSlide slide, Fill fill, FillReference FillReference)
         {
             if (FillReference != null)
             {
@@ -283,6 +475,7 @@ namespace HTEXLib.Helpers.ShapeHelpers
                     fill.type = 2;
                 }
             }
+            return fill;
         }
 
         private static Fill DoFillProperties(FillProperties shapeProperties , string partForm, PPTSlide slide)
@@ -333,8 +526,16 @@ namespace HTEXLib.Helpers.ShapeHelpers
             return fill;
         }
 
-        public static void DoTablePartStyleType(TablePartStyleType tablePartStyleType, PPTSlide slide, string type, string partForm) {
+        /// <summary>
+        /// 单元格样式表
+        /// </summary>
+        /// <param name="tablePartStyleType"></param>
+        /// <param name="slide"></param>
+        /// <param name="type"></param>
+        /// <param name="partForm"></param>
+        public static CellStyle DoTablePartStyleType(TablePartStyleType tablePartStyleType, PPTSlide slide, string type, string partForm) {
             //表格单元格文本样式。
+            CellStyle cellStyle = new CellStyle() { type= tablePartStyleType.GetType().Name};
             var TableCellTextStyle = tablePartStyleType.GetFirstChild<TableCellTextStyle>();
             if (TableCellTextStyle != null) {
                 FontStyle fontStyle = new FontStyle { };
@@ -420,120 +621,226 @@ namespace HTEXLib.Helpers.ShapeHelpers
                 }
                 //字体属性
                 var font = TableCellTextStyle.GetFirstChild<DocumentFormat.OpenXml.Drawing.Fonts>();
-                var LatinFont=  font.LatinFont;
-                var EastAsianFont= font.EastAsianFont; 
-                var ComplexScriptFont=  font.ComplexScriptFont;
-                if (EastAsianFont != null)
-                {
-                    fontStyle.family= DoTextFontType(EastAsianFont,slide);
-                }
-                if (ComplexScriptFont != null)
-                {
-                    fontStyle.family = DoTextFontType(ComplexScriptFont, slide);
-                }
-                if (LatinFont != null)
-                {
-                    fontStyle.family = DoTextFontType(LatinFont, slide);
-                }
-                var SupplementalFont=  font.GetFirstChild<SupplementalFont>();
-                if (SupplementalFont != null) {
-                    fontStyle.family = SupplementalFont.Typeface;
+                if (font != null) {
+                    var LatinFont = font.LatinFont;
+                    var EastAsianFont = font.EastAsianFont;
+                    var ComplexScriptFont = font.ComplexScriptFont;
+                    if (EastAsianFont != null)
+                    {
+                        fontStyle.family = DoTextFontType(EastAsianFont, slide);
+                    }
+                    if (ComplexScriptFont != null)
+                    {
+                        fontStyle.family = DoTextFontType(ComplexScriptFont, slide);
+                    }
+                    if (LatinFont != null)
+                    {
+                        fontStyle.family = DoTextFontType(LatinFont, slide);
+                    }
+                    var SupplementalFont = font.GetFirstChild<SupplementalFont>();
+                    if (SupplementalFont != null)
+                    {
+                        fontStyle.family = SupplementalFont.Typeface;
+                    }
+                    cellStyle.fontStyle = fontStyle;
                 }
             }
             //表格单元格样式。
             var TableCellStyle = tablePartStyleType.GetFirstChild<TableCellStyle>();
             if (TableCellStyle != null)
             {
+                List<CellBorder> cellBorders = new List<CellBorder>();
                 var TableCellBorders= TableCellStyle.TableCellBorders;
                 if (TableCellBorders != null) {
                     var LeftBorder = TableCellBorders.LeftBorder;
                     if (LeftBorder != null) {
-                        Border border=  DoOutline(LeftBorder.Outline, slide, "tbl");
+                        Border border=  DoOutline(LeftBorder.Outline, slide, type);
                         if (LeftBorder.LineReference!=null&& border.color.type == -1) {
                             border.color.solidFill=DoMatrixReferenceColors(LeftBorder.LineReference, slide);
                             border.color.type = 2;
                         }
+                        cellBorders.Add(new CellBorder() { border = border, type = "Left" });
                     }
                     var RightBorder = TableCellBorders.RightBorder;
                     if (RightBorder != null)
                     {
-                        Border border = DoOutline(RightBorder.Outline, slide, "tbl");
+                        Border border = DoOutline(RightBorder.Outline, slide, type);
                         if (RightBorder.LineReference != null && border.color.type == -1)
                         {
                             border.color.solidFill = DoMatrixReferenceColors(RightBorder.LineReference, slide);
                             border.color.type = 2;
                         }
+                        cellBorders.Add(new CellBorder() { border = border, type = "Right" });
                     }
                     var TopBorder = TableCellBorders.TopBorder;
                     if (TopBorder != null)
                     {
-                        Border border = DoOutline(TopBorder.Outline, slide, "tbl");
+                        Border border = DoOutline(TopBorder.Outline, slide, type);
                         if (TopBorder.LineReference != null && border.color.type == -1)
                         {
                             border.color.solidFill = DoMatrixReferenceColors(TopBorder.LineReference, slide);
                             border.color.type = 2;
                         }
+                        cellBorders.Add(new CellBorder() { border = border, type = "Top" });
                     }
                     var BottomBorder = TableCellBorders.BottomBorder;
                     if (BottomBorder != null)
                     {
-                        Border border = DoOutline(BottomBorder.Outline, slide, "tbl");
+                        Border border = DoOutline(BottomBorder.Outline, slide, type);
                         if (BottomBorder.LineReference != null && border.color.type == -1)
                         {
                             border.color.solidFill = DoMatrixReferenceColors(BottomBorder.LineReference, slide);
                             border.color.type = 2;
                         }
+                        cellBorders.Add(new CellBorder() { border = border, type = "Bottom" });
                     }
                     var InsideHorizontalBorder = TableCellBorders.InsideHorizontalBorder;
                     if (InsideHorizontalBorder != null)
                     {
-                        Border border = DoOutline(InsideHorizontalBorder.Outline, slide, "tbl");
+                        Border border = DoOutline(InsideHorizontalBorder.Outline, slide, type);
                         if (InsideHorizontalBorder.LineReference != null && border.color.type == -1)
                         {
                             border.color.solidFill = DoMatrixReferenceColors(InsideHorizontalBorder.LineReference, slide);
                             border.color.type = 2;
                         }
+                        cellBorders.Add(new CellBorder() { border = border, type = "InHor" });
                     }
                     var InsideVerticalBorder = TableCellBorders.InsideVerticalBorder;
                     if (InsideVerticalBorder != null)
                     {
-                        Border border = DoOutline(InsideVerticalBorder.Outline, slide, "tbl");
+                        Border border = DoOutline(InsideVerticalBorder.Outline, slide, type);
                         if (InsideVerticalBorder.LineReference != null && border.color.type == -1)
                         {
                             border.color.solidFill = DoMatrixReferenceColors(InsideVerticalBorder.LineReference, slide);
                             border.color.type = 2;
                         }
+                        cellBorders.Add(new CellBorder() { border = border, type = "InVer" });
                     }
                     var TopLeftToBottomRightBorder = TableCellBorders.TopLeftToBottomRightBorder;
                     if (TopLeftToBottomRightBorder != null)
                     {
-                        Border border = DoOutline(TopLeftToBottomRightBorder.Outline, slide, "tbl");
+                        Border border = DoOutline(TopLeftToBottomRightBorder.Outline, slide, type);
                         if (TopLeftToBottomRightBorder.LineReference != null && border.color.type == -1)
                         {
                             border.color.solidFill = DoMatrixReferenceColors(TopLeftToBottomRightBorder.LineReference, slide);
                             border.color.type = 2;
                         }
+                        cellBorders.Add(new CellBorder() { border = border, type = "Tl2br" });
                     }
                     var TopRightToBottomLeftBorder = TableCellBorders.TopRightToBottomLeftBorder;
                     if (TopRightToBottomLeftBorder != null)
                     {
-                        Border border = DoOutline(TopRightToBottomLeftBorder.Outline, slide, "tbl");
+                        Border border = DoOutline(TopRightToBottomLeftBorder.Outline, slide, type);
                         if (TopRightToBottomLeftBorder.LineReference != null && border.color.type == -1)
                         {
                             border.color.solidFill = DoMatrixReferenceColors(TopRightToBottomLeftBorder.LineReference, slide);
                             border.color.type = 2;
                         }
+                        cellBorders.Add(new CellBorder() { border = border, type = "Tr2bl" });
                     }
                 }
+                cellStyle.cellBorders = cellBorders;
                 var FillProperties = TableCellStyle.GetFirstChild<FillProperties>();
                 Fill fill = DoFillProperties(FillProperties, partForm, slide);
                 var FillReference = TableCellStyle.GetFirstChild<FillReference>();
-                DoFillReference(slide, fill, FillReference);
+                fill= DoFillReference(slide, fill, FillReference);
+                cellStyle.fill = fill;
                 //TODO
                 var Cell3DProperties = TableCellStyle.GetFirstChild<Cell3DProperties>();
+            }
+            return cellStyle;
+        }
+
+        public static CellStyle DoTableCellProperties(TableCellProperties shapeProperties, PPTSlide slide ,string type ,string partForm) {
+            CellStyle cellStyle = new CellStyle();
+
+            //TODO
+            var Cell3DProperties = shapeProperties.GetFirstChild<Cell3DProperties>();
+            Fill fill = new Fill() { type = -1 };
+            var gradFill = shapeProperties.GetFirstChild<GradientFill>();
+            if (gradFill != null)
+            {
+                fill.type = 2;
+                fill.gradientFill = DoGradientFill(gradFill, slide);
+            }
+            var noFill = shapeProperties.GetFirstChild<NoFill>();
+            if (noFill != null)
+            {
+                fill.type = 0;
+            }
+            var pattFill = shapeProperties.GetFirstChild<PatternFill>();
+            if (pattFill != null)
+            {
+                HtexPattFill htexPattFill = DoPattFill(pattFill, slide);
+                fill.type = 4;
+                fill.pattFill = htexPattFill;
+            }
+            var solidFill = shapeProperties.GetFirstChild<SolidFill>();
+            if (solidFill != null)
+            {
+                fill.type = 1;
+                fill.solidFill = DoSolidFill(solidFill, slide);
+            }
+            var groupFill = shapeProperties.GetFirstChild<GroupFill>();
+            if (groupFill != null)
+            {
+                fill.type = 5;
+                //  fill.solidFill = ReadSolidFillColors(new SolidFill(solidFill.ToString()), slide);
+            }
+            var blipFill = shapeProperties.GetFirstChild<DocumentFormat.OpenXml.Drawing.BlipFill>();
+            if (blipFill != null)
+            {
+                fill.type = 3;
+                fill.blipFill = DoBlipFill(blipFill, slide, partForm);
+                //  fill.solidFill = ReadSolidFillColors(new SolidFill(solidFill.ToString()), slide);
+            }
+            cellStyle.fill = fill;
+            List<CellBorder> cellBorders = new List<CellBorder>();
+            var LeftBorder = shapeProperties.LeftBorderLineProperties;
+            if (LeftBorder != null)
+            {
+                Border border = DoOutline(LeftBorder, slide, type);
+                 
+                cellBorders.Add(new CellBorder() { border = border, type = "Left" });
+            }
+            var  RightBorder = shapeProperties.RightBorderLineProperties;
+            if (RightBorder != null)
+            {
+                Border border = DoOutline(RightBorder, slide, type);
+
+                cellBorders.Add(new CellBorder() { border = border, type = "Right" });
+            }
+            var TopBorderLineProperties = shapeProperties.TopBorderLineProperties;
+            if (TopBorderLineProperties != null)
+            {
+                Border border = DoOutline(TopBorderLineProperties, slide, type);
+
+                cellBorders.Add(new CellBorder() { border = border, type = "Top" });
+            }
+            var BottomBorderLineProperties = shapeProperties.BottomBorderLineProperties;
+            if (BottomBorderLineProperties != null)
+            {
+                Border border = DoOutline(BottomBorderLineProperties, slide, type);
+                cellBorders.Add(new CellBorder() { border = border, type = "Bottom" });
+            }
 
+            var TopLeftToBottomRightBorderLineProperties = shapeProperties.TopLeftToBottomRightBorderLineProperties;
+            if (TopLeftToBottomRightBorderLineProperties != null)
+            {
+                // \
+                Border border = DoOutline(TopLeftToBottomRightBorderLineProperties, slide, type);
+                cellBorders.Add(new CellBorder() { border = border, type = "Tl2br" });
             }
+            var BottomLeftToTopRightBorderLineProperties = shapeProperties.BottomLeftToTopRightBorderLineProperties;
+            if (BottomLeftToTopRightBorderLineProperties != null)
+            {   // /
+                Border border = DoOutline(BottomLeftToTopRightBorderLineProperties, slide, type);
+                cellBorders.Add(new CellBorder() { border = border, type = "Tr2bl" });
+            }
+            cellStyle.cellBorders = cellBorders;
+            return cellStyle;
         }
+
         /// <summary>
         /// 
         /// </summary>
@@ -596,6 +903,9 @@ namespace HTEXLib.Helpers.ShapeHelpers
         {
             
             Fill fill = new Fill() { type = -1 };
+            if (shapeProperties == null) {
+                return fill;
+            }
             var gradFill = shapeProperties.GetFirstChild<GradientFill>();
             if (gradFill != null)
             {
@@ -782,7 +1092,7 @@ namespace HTEXLib.Helpers.ShapeHelpers
         /// </summary>
         /// <param name="shapeProperties"></param>
         /// <param name="slide"></param>
-        public static Border DoOutline(DocumentFormat.OpenXml.Drawing.Outline outline, PPTSlide slide,string  Shapetype) {
+        public static Border DoOutline(DocumentFormat.OpenXml.Drawing.LinePropertiesType outline, PPTSlide slide,string  Shapetype) {
             Border border = new Border() {color= new Fill { type=-1} };
             //20.1.10.35     EMUs. 1 pt = 12700 EMUs.
             double? Width = null;
@@ -799,9 +1109,9 @@ namespace HTEXLib.Helpers.ShapeHelpers
             // Center = 0,
             // Insert = 1
             //20.1.10.39
-            int? algn =  null;
+           string algn =  null;
             if (outline.Alignment != null) {
-                algn = Convert.ToInt32(outline.Alignment);
+                algn = outline.Alignment;
             }
 
             /*  20.1.10.15  复合类型
@@ -811,9 +1121,9 @@ namespace HTEXLib.Helpers.ShapeHelpers
                 ThinThick = 3, 细到粗
                 Triple = 4 三线
              */
-            int? cmpd = null ;
+            string  cmpd = null ;
             if (outline.CompoundLineType!=null) {
-                cmpd = Convert.ToInt32(outline.CompoundLineType);
+                cmpd = outline.CompoundLineType;
             }
             
             /*  20.1.10.31 线端类型 
@@ -821,9 +1131,9 @@ namespace HTEXLib.Helpers.ShapeHelpers
                 Square = 1,圆
                 Flat = 2 平
              */
-            int? cap =null;
+            string cap =null;
             if (outline.CapType != null) {
-                cap = Convert.ToInt32(outline.CapType);
+                cap = outline.CapType;
             }
             border.outline = new HtexOutline { Width = Width, algn = algn, cmpd = cmpd, cap = cap };
             var gradFill = outline.GetFirstChild<GradientFill>();
@@ -1447,6 +1757,21 @@ namespace HTEXLib.Helpers.ShapeHelpers
             if (string.IsNullOrEmpty(FontColor)) {
                 FontColor = ReadAccentSchemeColors(schemeColor, slide);
             }
+            if (FontColor.Replace("#", "") == "") {
+                var chren= slide.SlideLayoutPart.SlideMasterPart.ThemePart.Theme.ThemeElements.ColorScheme.ChildElements;
+                foreach(var cl in chren) {
+
+                    if (schemeColor.Val == cl.LocalName) {
+                        if (schemeColor.Val == "dk1" || schemeColor.Val == "lt1")
+                        {
+                            FontColor ="#"+ cl.GetFirstChild<SystemColor>().LastColor;
+                        }
+                        else {
+                            FontColor ="#"+cl.GetFirstChild<RgbColorModelHex>().Val.Value; ;
+                        }
+                    }
+                }
+            }
             return FontColor;
         }
 

+ 138 - 0
HTEXLib/Helpers/ShapeHelpers/ShaHashHelper.cs

@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace HTEXLib.Helpers.ShapeHelpers
+{
+    public class ShaHashHelper
+    {
+
+        public static string GetSHA1(string Code)
+        {
+            var resbuffer = Encoding.Default.GetBytes(Code);
+            HashAlgorithm iSha = new SHA1CryptoServiceProvider();
+            resbuffer = iSha.ComputeHash(resbuffer);
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i < resbuffer.Length; i++)
+            {
+                builder.Append(resbuffer[i].ToString("x2"));
+            }
+            return builder.ToString();
+            //return Convert.ToBase64String(strRes);
+        }
+        public static string GetSHA1(byte[] buffer)
+        {
+            var resbuffer = buffer;
+            HashAlgorithm iSha = new SHA1CryptoServiceProvider();
+            resbuffer = iSha.ComputeHash(buffer);
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i < resbuffer.Length; i++)
+            {
+                builder.Append(resbuffer[i].ToString("x2"));
+            }
+            return builder.ToString();
+            // return Convert.ToBase64String(strRes);
+        }
+        public static string GetSHA1(Stream stream)
+        {
+            byte[] buffer = new byte[stream.Length];
+
+            stream.Read(buffer, 0, buffer.Length);
+            // stream.Close();
+            var resbuffer = buffer;
+            HashAlgorithm iSha = new SHA1CryptoServiceProvider();
+            resbuffer = iSha.ComputeHash(buffer);
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i < resbuffer.Length; i++)
+            {
+                builder.Append(resbuffer[i].ToString("x2"));
+            }
+            return builder.ToString();
+            // return Convert.ToBase64String(strRes);
+        }
+        public static string GetSHA1(string Code, string SecretKey)
+        {
+            HMACSHA1 hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(SecretKey));
+            byte[] resbuffer = hmacsha1.ComputeHash(Encoding.UTF8.GetBytes(Code));
+
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i < resbuffer.Length; i++)
+            {
+                builder.Append(resbuffer[i].ToString("x2"));
+            }
+            return builder.ToString();
+            //return Convert.ToBase64String(rstRes); 
+        }
+        public static string GetSHA1(byte[] buffer, string SecretKey)
+        {
+            HMACSHA1 hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(SecretKey));
+            byte[] resbuffer = hmacsha1.ComputeHash(buffer);
+
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i < resbuffer.Length; i++)
+            {
+                builder.Append(resbuffer[i].ToString("x2"));
+            }
+            return builder.ToString();
+            //eturn Convert.ToBase64String(buffer);
+        }
+        public static string GetSHA256(byte[] buffer)
+        {
+            SHA256Managed Sha256 = new SHA256Managed();
+            byte[] resbuffer = Sha256.ComputeHash(buffer);
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i < resbuffer.Length; i++)
+            {
+                builder.Append(resbuffer[i].ToString("x2"));
+            }
+            return builder.ToString();
+            //return Convert.ToBase64String(retval);
+
+        }
+
+        public static string GetSHA256(string Code)
+        {
+            SHA256Managed Sha256 = new SHA256Managed();
+            byte[] resbuffer = Sha256.ComputeHash(Encoding.UTF8.GetBytes(Code));
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i < resbuffer.Length; i++)
+            {
+                builder.Append(resbuffer[i].ToString("x2"));
+            }
+            return builder.ToString();
+            //return Convert.ToBase64String(retval);
+        }
+
+        public static string GetSHA256(byte[] buffer, string SecretKey)
+        {
+            byte[] messageBytes = buffer;
+            byte[] keyByte = Encoding.UTF8.GetBytes(SecretKey);
+            var hmacsha256 = new HMACSHA256(keyByte);
+            byte[] resbuffer = hmacsha256.ComputeHash(messageBytes);
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i < resbuffer.Length; i++)
+            {
+                builder.Append(resbuffer[i].ToString("x2"));
+            }
+            return builder.ToString();
+            //return Convert.ToBase64String(hashmessage);
+        }
+
+        public static string GetSHA256(string Code, string SecretKey)
+        {
+            byte[] messageBytes = Encoding.UTF8.GetBytes(Code);
+            byte[] keyByte = Encoding.UTF8.GetBytes(SecretKey);
+            var hmacsha256 = new HMACSHA256(keyByte);
+            byte[] resbuffer = hmacsha256.ComputeHash(messageBytes);
+            StringBuilder builder = new StringBuilder();
+            for (int i = 0; i < resbuffer.Length; i++)
+            {
+                builder.Append(resbuffer[i].ToString("x2"));
+            }
+            return builder.ToString();
+            //return Convert.ToBase64String(resbuffer);
+        }
+    }
+}

+ 14 - 1
HTEXLib/Helpers/ShapeHelpers/ShapeHelper.cs

@@ -7,6 +7,7 @@ using System.Runtime;
 using System.Xml.Linq;
 using System.Xml.XPath;
 using DocumentFormat.OpenXml;
+using DocumentFormat.OpenXml.Drawing;
 
 namespace HTEXLib
 {
@@ -96,6 +97,8 @@ namespace HTEXLib
         /// <returns></returns>
         public static string ColorToning(string nodeXml, string colorHex)
         {
+            //ColorTransform
+            //PercentageType percentageType = new PercentageType();
             if (string.IsNullOrEmpty(colorHex)) { return null; }
             ColorConverter converter = new ColorConverter();
             XmlDocument doc = new XmlDocument();
@@ -143,6 +146,7 @@ namespace HTEXLib
                 Color color = ColorTranslator.FromHtml("#" + colorHex);
                 //color.A * (int.Parse(alpha.Value) / 100000);
                 color = Color.FromArgb(color.A- color.A * (int.Parse(alphaOff.Value) / 100000), color.R, color.G, color.B);
+                colorHex= color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2");
             }
             XmlNode shade = doc.SelectSingleNode("//a:shade/@val", xmlnsManager);
             if (shade != null)
@@ -157,14 +161,23 @@ namespace HTEXLib
                 //color.A * (int.Parse(alpha.Value) / 100000);
                 //TODO是用255计算 还是颜色本身的A alpha计算
                 color = Color.FromArgb(color.A * (int.Parse(alpha.Value) / 100000), color.R,color.G,color.B);
+                colorHex = color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2");
             }
             //TODO  //颜色调和 说明网站  https://c-rex.net/projects/samples/ooxml/e1/Part4/OOXML_P4_DOCX_comp_topic_ID0EATEJB.html
             XmlNode comp = doc.SelectSingleNode("//a:comp", xmlnsManager);
             if (comp != null) {
                 colorHex = converter.SetComp(colorHex);
             }
-            XmlNode inv = doc.SelectSingleNode("//a:inv/@val", xmlnsManager);
+            //反色
+            XmlNode inv = doc.SelectSingleNode("//a:inv", xmlnsManager);
+            if (inv != null) {
+                Color color = ColorTranslator.FromHtml("#" + colorHex);
+                colorHex = (255- color.R).ToString("X2") + (255 - color.G).ToString("X2") + (255 - color.B).ToString("X2");
+            }
             XmlNode alphaMod = doc.SelectSingleNode("//a:alphaMod/@val", xmlnsManager);
+            if (alphaMod != null) { 
+            
+            }
             XmlNode gray = doc.SelectSingleNode("//a:gray/@val", xmlnsManager);
             XmlNode hue = doc.SelectSingleNode("//a:hue/@val", xmlnsManager);
             XmlNode sat = doc.SelectSingleNode("//a:sat/@val", xmlnsManager);

+ 3 - 3
HTEXLib/Models/Border.cs

@@ -34,7 +34,7 @@ namespace HTEXLib
         ///Insert = 1
         ///20.1.10.39
         /// </summary>
-        public int? algn { get; set; }
+        public string algn { get; set; }
         /// <summary>
         ///  20.1.10.15
         ///Single = 0,
@@ -43,14 +43,14 @@ namespace HTEXLib
         ///       ThinThick = 3,
         ///        Triple = 4
         /// </summary>
-        public int? cmpd { get; set; }
+        public string cmpd { get; set; }
         /// <summary>
         /// 20.1.10.31
         /// Round = 0,
         /// Square = 1,
         ///  Flat = 2
         /// </summary>
-        public int? cap { get; set; }
+        public string cap { get; set; }
     }
 
 }

+ 4 - 2
HTEXLib/Models/Chart.cs

@@ -7,9 +7,11 @@ namespace HTEXLib
     public   class Chart : Item
     {
         public  List<CommonChart> charts { get; set; }
-        public List<Paragraph> title { get; set; }
+        public Shape title { get; set; }
+
+        public Fill fill { get; set; } = new Fill() { type = -1 };
+        public Border border { get; set; } = new Border();
 
-       
     }
 
     public abstract class CommonChart {

+ 760 - 0
HTEXLib/Models/HTEX/HtexChart.cs

@@ -0,0 +1,760 @@
+using DocumentFormat.OpenXml;
+using DocumentFormat.OpenXml.Drawing;
+using DocumentFormat.OpenXml.Drawing.Charts;
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Presentation;
+using HTEXLib.Helpers.ShapeHelpers;
+using HTEXLib.Models.Inner;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Xml.Linq;
+
+namespace HTEXLib.Models.HTEX
+{
+    public class HtexChart : HtexElement
+    {
+        public HtexChart(string id, double rot, double width, double height,
+                                   double top, double left, bool invisible,
+                                   bool animatable, int index, DocumentFormat.OpenXml.Drawing.Charts.ChartReference Chart, PPTSlide slide, string partForm)
+        {
+            base.slide = slide;
+            this.rot = rot;
+            this.Chart = Chart;
+            base.id = id;
+            base.top = top;
+            base.left = left;
+            base.width = width;
+            base.height = height;
+            base.invisible = invisible;
+            base.animatable = animatable;
+            base.index = index;
+            base.type = "Chart";
+            base.partForm = partForm;
+        }
+        public DocumentFormat.OpenXml.Drawing.Charts.ChartReference Chart { get; set; }
+        public override List<Item> DrawElement()
+        {
+            var ChartNode = slide.SlidePart.Parts.Where(x => x.RelationshipId == Chart.Id).FirstOrDefault();
+            var url = ChartNode.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
+            var ChartParts = slide.SlidePart.GetPartsOfType<DocumentFormat.OpenXml.Packaging.ChartPart>();
+            if (ChartParts != null) {
+                var chart = ChartParts.Where(x => x.Uri.ToString() == url).FirstOrDefault() ;
+                
+                if (chart != null) {
+                    ChartColorStylePart ChartColorStylePart = null;
+                    ChartStylePart ChartStylePart = null;
+                    foreach (var idp in chart.Parts) {
+                        if (idp.OpenXmlPart is ChartColorStylePart ChartColorStyleParts) {
+                            ChartColorStylePart = ChartColorStyleParts;
+                        }
+                        if (idp.OpenXmlPart is ChartStylePart ChartStyleParts)
+                        {
+                            ChartStylePart = ChartStyleParts;
+                        }
+                    }
+                    
+                    var ChartStyleChildren = ChartStylePart.ChartStyle.ChildElements;
+                    foreach (var child in ChartStyleChildren) {
+                        if (child is DocumentFormat.OpenXml.Office2013.Drawing.ChartStyle.StyleEntry StyleEntry) {
+                          
+                            DoStyleEntry(StyleEntry);
+                        }
+                        ///OfficeArtExtensionList   cs: extLst
+                       // MarkerLayoutProperties    cs: dataPointMarkerLayout
+
+                    }
+                    Chart charts= DrawChart(chart.ChartSpace);
+                    return new List<Item> { charts };
+                }
+            }
+            return null; 
+        }
+
+        public Chart DrawChart(DocumentFormat.OpenXml.Drawing.Charts.ChartSpace chartSpace) {
+            var Chart = chartSpace.GetFirstChild<DocumentFormat.OpenXml.Drawing.Charts.Chart>();
+            var ShapeProperties = chartSpace.GetFirstChild<DocumentFormat.OpenXml.Drawing.Charts.ShapeProperties>();
+            HTEXLib.Models.HTEX.ShapeStyle shapeStyleChart= PPTXHelper.DoShapeProperties(ShapeProperties,slide,type,partForm);
+            var TextProperties = chartSpace.GetFirstChild<TextProperties>();
+            var style = chartSpace.GetFirstChild<DocumentFormat.OpenXml.Drawing.Charts.Style>();
+            var ColorMapOverride = chartSpace.GetFirstChild<DocumentFormat.OpenXml.Drawing.Charts.ColorMapOverride>();
+            var style2010 = chartSpace.GetFirstChild<DocumentFormat.OpenXml.Office2010.Drawing.Charts.Style>();
+            var UserShapesReference = chartSpace.GetFirstChild<UserShapesReference>();
+            var charts = DoPlotArea(Chart.PlotArea);
+            var ChartShapeProperties = Chart.Title.ChartShapeProperties;
+            ShapeStyle shapeStyle = PPTXHelper.DoShapeProperties(ChartShapeProperties, slide, type, partForm);
+            LinkedList<PPTParagraph> PPTParagraphs=  DoChartTitle(Chart.Title);
+            List<Paragraph> paragraphs = DrawText(PPTParagraphs);
+            Shape shape= new Shape { type = "Shape", shapeType = "Rect", paragraph = paragraphs, fill = shapeStyle!=null? shapeStyle.fill:null, border = shapeStyle != null ? shapeStyle.border:null };
+            return new Chart { charts=charts,title=shape, fill= shapeStyleChart !=null ?shapeStyleChart.fill:null,border= shapeStyleChart !=null? shapeStyleChart.border:null};
+        }
+        public LinkedList<PPTParagraph> DoChartTitle(DocumentFormat.OpenXml.Drawing.Charts.Title title)
+        {
+            if (title.ChartText == null)
+            {
+                return null;
+            }
+            LinkedList<PPTParagraph> Texts = new LinkedList<PPTParagraph>();
+            var BodyProperties = title.ChartText.RichText.BodyProperties;
+            var ListStyle = title.ChartText.RichText.ListStyle;
+
+            var Layout = title.Layout;
+          
+            if (BodyProperties == null)
+            {
+                BodyProperties = title.TextProperties.BodyProperties;
+            }
+            if (ListStyle != null)
+            {
+                ListStyle = title.TextProperties.ListStyle;
+            }
+            if (ListStyle != null)
+            {
+                //TODO文本层级内容
+            }
+            if (BodyProperties.Anchor != null)
+            {
+                string VerticalAlign = BodyProperties.Anchor.Value.ToString();
+            }
+
+            int fontScale = 100000;
+            if (BodyProperties.GetFirstChild<NormalAutoFit>() != null &&
+                    BodyProperties.GetFirstChild<NormalAutoFit>().FontScale != null)
+            {
+                fontScale = BodyProperties.GetFirstChild<NormalAutoFit>().FontScale.Value;
+            }
+            var ExtensionList = title.ExtensionList;
+            var Paragraphs = title.ChartText.RichText.Elements<DocumentFormat.OpenXml.Drawing.Paragraph>();
+            foreach (var paragraph in Paragraphs)
+            {
+                PlaceholderShape placeholder = null;
+                var par = new PPTParagraph(slide, placeholder)
+                {
+                    Paragraph = index++
+                };
+                if (paragraph.ParagraphProperties != null)
+                {
+                    int level = paragraph.ParagraphProperties.Level == null ?
+                               -1 : paragraph.ParagraphProperties.Level.Value;
+
+                    par.Level = level;
+                }
+                par.SetParagraphProperties(paragraph, slide.SlidePart,
+                                        slide.shapeListStyleMaster, slide.shapeListStyleLayout);
+                bool hasText = false;
+                foreach (var obj in paragraph.ChildElements)
+                {
+                    hasText = GetParagraphChildElements(title.ChartText.RichText, par, hasText, obj, fontScale);
+                }
+                //This is because when we set paragraph properties we add the bullet to the text runs.
+                //If we don't have text it still outputs the bullet character. 
+                if (par.bullet != null && hasText)
+                {
+                    par.RunPropList.Insert(0, par.bullet);
+                }
+                Texts.AddLast(par);
+            }
+            return Texts;
+        }
+        public List<Paragraph> DrawText(LinkedList<PPTParagraph> Texts)
+        {
+            if (Texts == null) {
+                return null;
+            }
+            List<Paragraph> Paragraphs = new List<Paragraph>();
+            foreach (var par in Texts)
+            {
+                double paragraphTop = par.getSpaceBeforePoints();
+                Paragraph paragraph = new HTEXLib.Paragraph { animatable = par.Animatable, invisible = par.Invisible };
+                int newTop = par.getSpaceBeforePoints();
+                int left = 0;
+                List<HtexText> textElements = new List<HtexText>();
+                if (par.RunPropList == null || par.RunPropList.Count == 0 && par.defaultRunProperties != null)  //Only paragraph!
+                {
+                    float points = float.Parse(par.defaultRunProperties.FontSize.ToString()) * 72.0F / 96.0F;
+                    System.Drawing.Font font = new System.Drawing.Font(par.defaultRunProperties.FontFamily.ToString(), points);
+                    newTop = font.Height;
+                }
+                List<HtexText> processedElements = new List<HtexText>();
+                IEnumerable<PPTRunProperties> pPTRunProperties = breakTextsToShape(par);
+                foreach (var text in pPTRunProperties)
+                {
+                    float points = float.Parse(text.FontSize.ToString()) * 72.0F / 96.0F;
+                    System.Drawing.Font font = new System.Drawing.Font(text.FontFamily.ToString(), points);
+                    if (text.Bold) font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Bold);
+                    else if (text.Italic)
+                        font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Italic);
+                    else if (text.Underline != null && text.Underline.Equals("Single"))
+                        font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Underline);
+                    newTop = font.Height > newTop ? font.Height : newTop;
+                    newTop = par.getLineSpacingInPointsFromFont(newTop);
+                    if (text.isBreak)
+                    {
+                        top += newTop;
+                        left = 0;
+                        fixLeftSpacingForAlignment(processedElements, par, font);
+                        processedElements.Clear();
+                        continue;
+                    }
+                    String currentString = text.Text.TrimEnd() + getStringFromTextElements(processedElements);
+                    HtexText t1 = new HtexText(left: left,
+                                            top: top,
+                                            fontFamily: text.FontFamily,
+                                            fontColor: text.FontColor,
+                                            fontSize: text.FontSize,
+                                            isBullet: text.isBullet,
+                                            bold: text.Bold,
+                                            italic: text.Italic,
+                                            underline: text.Underline,
+                                            id: id,
+                                            slideIndex: slide.slideIndex)
+                    {
+                        Rotate = this.rot
+                    };
+                    t1.width = MeasureString(text.Text, font);
+
+                    if (text.isBullet && text.Text != null && text.Text.Contains("rId"))
+                    {
+                        t1.PictureBullet = true;
+                        t1.width = text.bulletSize;
+                        t1.bulletSize = text.bulletSize;
+                        newTop = text.bulletSize;
+                    }
+                    t1.Text = text.Text;
+                    textElements.Add(t1);
+                    processedElements.Add(t1);
+                }
+                fixLeftSpacingForAlignment(processedElements, par);
+
+                HtexText lastTxt = null;
+                List<HtexText> mergedTextElements = new List<HtexText>();
+                foreach (HtexText textElement in textElements)
+                {
+                    if (lastTxt == null || !lastTxt.sameProps(textElement))
+                        mergedTextElements.Add(textElement);
+                    else
+                        mergedTextElements[mergedTextElements.Count - 1].Text += textElement.Text;
+
+                    lastTxt = textElement;
+                }
+
+                //foreach (HtexText textElement in mergedTextElements) {
+                // shapeBuilder.Append(textElement.DrawElement());
+                //}
+
+                top += newTop;
+                top += par.getSpaceAfterPoints(newTop);
+                top += par.getSpaceBeforePoints(newTop);
+                paragraph.texts = textElements;
+                Paragraphs.Add(paragraph);
+            }
+            return Paragraphs;
+        }
+        private String getStringFromTextElements(List<HtexText> elements)
+        {
+            if (elements == null || elements.Count == 0)
+                return "";
+            StringBuilder result = new StringBuilder();
+            foreach (HtexText el in elements)
+            {
+                result.Append(el.Text);
+            }
+            return result.ToString();
+        }//We have two similar methods - this one is better because it measures the whole string with the font. 
+        private void fixLeftSpacingForAlignment(List<HtexText> textElements, PPTParagraph par, System.Drawing.Font font)
+        {
+            int combinedWidth = 0;
+
+            StringBuilder combinedText = new StringBuilder();
+            foreach (HtexText textElement in textElements)
+            {
+                if (textElement.PictureBullet)
+                    combinedWidth += textElement.bulletSize;
+                else
+                    combinedText.Append(textElement.Text);
+            }
+            int bulletOffset = 0;
+            if (par.bullet != null && textElements.Count > 0 && !textElements[0].isBullet)
+            {
+                bulletOffset = par.bullet.bulletSize;
+                combinedWidth += par.bullet.bulletSize;
+            }
+            combinedWidth += MeasureString(combinedText.ToString(), font);
+
+            double firstLeft = 0;
+            if ("Center".Equals(par.Align))
+                firstLeft = ((this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth) / 2;
+            else if ("Right".Equals(par.Align))
+                firstLeft = (this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth;
+            combinedText = new StringBuilder();
+            combinedWidth = 0; //Now used only for picture bullets!
+            foreach (HtexText textElement in textElements)
+            {
+                textElement.setLeft(firstLeft + par.Indent + bulletOffset + par.marginLeft + combinedWidth + MeasureString(combinedText.ToString(), font));
+                if (textElement.PictureBullet)
+                    combinedWidth += textElement.bulletSize;
+                else
+                    combinedText.Append(textElement.Text);
+            }
+        }//We have two similar methods. This is worse because it uses the Width property of each element instead of measuring the whole string. 
+        //There is mistake in the calculations coming from that and the difference is bigger when there are more elements. 
+        private void fixLeftSpacingForAlignment(List<HtexText> textElements, PPTParagraph par)
+        {
+            int combinedWidth = 0;
+
+            foreach (HtexText textElement in textElements)
+                combinedWidth += textElement.width;
+            int bulletOffset = 0;
+            if (par.bullet != null && textElements.Count > 0 && !textElements[0].isBullet)
+            {
+                combinedWidth += par.bullet.bulletSize;
+                bulletOffset = par.bullet.bulletSize;
+            }
+
+            double currentLeft = 0;
+            if ("Center".Equals(par.Align))
+                currentLeft = ((this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth) / 2;
+            else if ("Right".Equals(par.Align))
+                currentLeft = (this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth;
+
+            foreach (HtexText textElement in textElements)
+            {
+                textElement.setLeft(currentLeft + par.Indent + bulletOffset + par.marginLeft);
+                currentLeft += textElement.width;
+            }
+        }
+        private IEnumerable<PPTRunProperties> breakTextsToShape(PPTParagraph par)
+        {
+            List<PPTRunProperties> list = par.RunPropList;
+            List<PPTRunProperties> result = new List<PPTRunProperties>();
+            String previousToken = null;
+            int bulletSize = 0;
+            foreach (var text in list)
+            {
+                float points = float.Parse(text.FontSize.ToString()) * 72.0F / 96.0F;
+                System.Drawing.Font font = new System.Drawing.Font(text.FontFamily.ToString(), points);
+                if (text.Bold) font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Bold);
+                else if (text.Italic) font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Italic);
+                else if (text.Underline != null && text.Underline.Equals("Single"))
+                    font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Underline);
+
+                int size = 0;
+                if (text.isBullet && text.Text != null && text.Text.Contains("rId"))
+                    bulletSize = text.bulletSize;
+                else
+                    size = MeasureString((previousToken == null ? "" : previousToken + " ") + text.Text, font);
+                if (text.isBreak || size + bulletSize < this.width - par.Indent - par.marginLeft - par.marginRight)//- Shape.LeftInset - Shape.RightInset)
+                {
+                    if (text.Text != null && text.Text.Trim() != "" && !(text.isBullet && text.Text.Contains("rId")))
+                    {
+                        previousToken = (previousToken == null ? "" : previousToken) + text.Text;
+                    }
+                    if (text.isBreak)
+                        previousToken = null;
+                    result.Add(text);
+                    continue;
+                }
+
+                //   previousToken = null;
+
+                string[] tokens = text.Text.Split(' ');
+                int index = 0;
+                foreach (string token in tokens)
+                {
+                    index++;
+                    int combinedSize = MeasureString((previousToken == null ? "" : previousToken + " ") + token, font);
+
+                    if (combinedSize + bulletSize > this.width - par.Indent - par.marginLeft - par.marginRight)//- Shape.LeftInset - Shape.RightInset)
+                    {
+                        PPTRunProperties temp = new PPTRunProperties(text);
+                        temp.Text = "";
+                        temp.isBreak = true;
+                        result.Add(temp);
+
+                        temp = new PPTRunProperties(text);
+                        temp.Text = index < tokens.Length ? token + " " : token;
+                        result.Add(temp);
+                        previousToken = token;
+                    }
+                    else
+                    {
+                        PPTRunProperties temp = new PPTRunProperties(text);
+                        temp.Text = index < tokens.Length ? token + " " : token;
+                        result.Add(temp);
+                        previousToken = (previousToken == null ? "" : previousToken + " ") + token;
+                    }
+                }
+            }
+            return result;
+        }
+        public static int MeasureString(string s, System.Drawing.Font font)
+        {
+            s = s.Replace("\t", "aaaa");//TODO the replace is dirty hack for measuring tabulations
+
+            StringFormat stringFormat = new StringFormat(StringFormat.GenericTypographic);
+            CharacterRange[] rng = { new CharacterRange(0, s.Length) };
+            stringFormat.SetMeasurableCharacterRanges(rng);
+            Graphics g = Graphics.FromImage(new Bitmap(100, 100));
+            //Use measure character ranges with a big box because we used this for measurement only
+            //Later we might better use this for drawing the text. 
+            Region[] regions = g.MeasureCharacterRanges(s, font, new System.Drawing.Rectangle(0, 0, 10000, 3000), stringFormat);
+            foreach (Region region in regions)
+            {
+                RectangleF rect = region.GetBounds(g);
+                return (int)System.Math.Round(rect.Width);
+            }
+            return 0;
+
+            // 
+            //             SizeF result;
+            //             using (var image = new Bitmap(1, 1))
+            //             {
+            //                 using (var g = Graphics.FromImage(image))
+            //                 {
+            //                     result = g.MeasureString(s, font);
+            //                 }
+            //             }
+            // 
+            //             return result.ToSize();
+        }
+       
+        private bool GetParagraphChildElements(RichText shape, PPTParagraph par, bool hasText, OpenXmlElement obj, int fontScale)
+        {
+            LinkedList<string> effectShapes = new LinkedList<string>();
+            if (obj is Run)
+            {
+                Run run = (Run)obj;
+                hasText = true;
+                PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
+                runProp.Text = run.Text.Text;
+                runProp.SetRunProperties(run.RunProperties, shape, ref effectShapes);
+                runProp.FontSize = System.Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
+                par.RunPropList.Add(runProp);
+            }
+
+            else if (obj is Field)
+            {
+                Field run = (Field)obj;
+                hasText = true;
+                PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
+                runProp.Text = run.Text.Text;
+                runProp.SetRunProperties(run.RunProperties, shape, ref effectShapes);
+                runProp.FontSize = System.Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
+                par.RunPropList.Add(runProp);
+            }
+
+            else if (obj is Break)
+            {
+                Break aBreak = (Break)obj;
+                PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
+                runProp.SetRunProperties(aBreak.RunProperties, shape, ref effectShapes);
+                runProp.FontSize = System.Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
+                runProp.isBreak = true;
+                par.RunPropList.Add(runProp);
+            }
+            return hasText;
+        }
+        public List<CommonChart> DoPlotArea(PlotArea plotArea) {
+            List<CommonChart> charts = new List<CommonChart>();
+            foreach (var child in plotArea.ChildElements)
+            {
+                string key = child.LocalName;
+                IEnumerable<XElement> serNodes = null;
+                switch (key)
+                {
+                    //break块中不可以随意更换,此条件用于归类不同从Chart
+                    case "pieChart":
+                    case "ofPieChart":
+                    case "pie3DChart":
+                    case "doughnutChart":
+                        PieChart pieChart = new PieChart { chartType = "pie" };
+                        if (key.Equals("pie3DChart"))
+                        {
+                            pieChart.is3D = true;
+                        }
+                        pieChart.pieType = key;
+                        if (key.Equals("ofPieChart"))
+                        {
+                            var ofPieType = child.GetTextByPath("c:ofPieType");
+                            if (ofPieType != null)
+                            {
+                                //ofPieChart-pie ofPieChart-bar  子母饼图
+                                pieChart.pieType += "-" + ofPieType.Attribute("val").Value;
+                            }
+                        }
+                        serNodes = child.GetTextByPathList("c:ser");
+                        pieChart.datas = ExtractChartData(serNodes);
+                        charts.Add(pieChart);
+                        break;
+                    case "lineChart":
+                    case "line3DChart":
+                        LineChart lineChart = new LineChart { chartType = "line" };
+                        if (key.Equals("line3DChart"))
+                        {
+                            lineChart.is3D = true;
+                        }
+                        lineChart.lineType = key;
+                        var LineGrouping = child.GetTextByPath("c:grouping");
+                        if (LineGrouping != null)
+                        {
+                            //standard stacked percentStacked
+                            lineChart.lineType += "-" + LineGrouping.Attribute("val").Value;
+                        }
+                        serNodes = child.GetTextByPathList("c:ser");
+                        lineChart.datas = ExtractChartData(serNodes);
+                        charts.Add(lineChart);
+                        break;
+                    case "barChart":
+                    case "bar3DChart":
+                        var barDir = child.GetTextByPath("c:barDir");
+                        if (barDir != null)
+                        {
+                            if (barDir.Attribute("val").Value.Equals("bar"))
+                            {
+                                BarChart barChart = new BarChart { chartType = "bar" };
+                                charts.Add(barChart);
+                                if (key.Equals("bar3DChart"))
+                                {
+                                    barChart.is3D = true;
+                                }
+
+                                barChart.barType = key;
+                                var BarGrouping = child.GetTextByPath("c:grouping");
+                                if (BarGrouping != null)
+                                {
+                                    //standard stacked percentStacked
+                                    barChart.barType += "-" + BarGrouping.Attribute("val").Value;
+                                }
+                                serNodes = child.GetTextByPathList("c:ser");
+                                barChart.datas = ExtractChartData(serNodes);
+                                charts.Add(barChart);
+                            }
+                            else if (barDir.Attribute("val").Value.Equals("col"))
+                            {
+                                ColChart colChart = new ColChart { chartType = "col" };
+                                if (key.Equals("bar3DChart"))
+                                {
+                                    colChart.is3D = true;
+                                }
+                                colChart.colType = key.Replace("bar", "col");
+                                var ColGrouping = child.GetTextByPath("c:grouping");
+                                if (ColGrouping != null)
+                                {
+                                    //standard stacked percentStacked
+                                    colChart.colType += "-" + ColGrouping.Attribute("val").Value;
+                                }
+                                serNodes = child.GetTextByPathList("c:ser");
+                                colChart.datas = ExtractChartData(serNodes);
+                                charts.Add(colChart);
+                            }
+                        }
+                        break;
+                    case "areaChart":
+                    case "area3DChart":
+                        AreaChart areaChart = new AreaChart { chartType = "area" };
+                        if (key.Equals("area3DChart"))
+                        {
+                            areaChart.is3D = true;
+                        }
+                        areaChart.areaType = key;
+                        var AreaGrouping = child.GetTextByPath("c:grouping");
+                        if (AreaGrouping != null)
+                        {
+                            //standard stacked percentStacked
+                            areaChart.areaType += "-" + AreaGrouping.Attribute("val").Value;
+                        }
+                        serNodes = child.GetTextByPathList("c:ser");
+                        areaChart.datas = ExtractChartData(serNodes);
+                        charts.Add(areaChart);
+                        break;
+                    case "scatterChart":
+                    case "bubbleChart":
+                        ScatterChart scatterChart = new ScatterChart { chartType = "scatter" };
+                        scatterChart.scatterType = key;
+                        if (key.Equals("scatterChart"))
+                        {
+                            var ScatterStyle = child.GetTextByPath("c:scatterStyle");
+                            if (ScatterStyle != null)
+                            {
+                                scatterChart.scatterType += "-" + ScatterStyle.Attribute("val").Value.Replace("Marker", "");
+                            }
+                        }
+                        serNodes = child.GetTextByPathList("c:ser");
+                        scatterChart.datas = ExtractChartData(serNodes);
+                        charts.Add(scatterChart);
+                        break;
+                    case "radarChart":
+                        RadarChart radarChart = new RadarChart { chartType = "radar" };
+                        radarChart.radarType = key;
+                        var RadarStyle = child.GetTextByPath("c:radarStyle");
+                        if (RadarStyle != null)
+                        {
+                            radarChart.radarType += "-" + RadarStyle.Attribute("val").Value;
+                        }
+                        serNodes = child.GetTextByPathList("c:ser");
+                        radarChart.datas = ExtractChartData(serNodes);
+                        charts.Add(radarChart);
+                        break;
+                    case "plotAreaRegion":
+                        PlotAreaChart plotAreaChart = new PlotAreaChart { chartType = "plotArea" };
+                        plotAreaChart.plotAreaType = key;
+                        var PlotSeries = child.GetTextByPath("cx:series");
+                        if (PlotSeries != null)
+                        {
+                            plotAreaChart.plotAreaType += "-" + PlotSeries.Attribute("val").Value;
+                        }
+                        serNodes = child.GetTextByPathList("c:ser");
+                        plotAreaChart.datas = ExtractChartData(serNodes);
+                        charts.Add(plotAreaChart);
+                        break;
+                    case "stockChart":
+                        StockChart stockChart = new StockChart { chartType = "stock" };
+                        stockChart.stockType = key;
+                        serNodes = child.GetTextByPathList("c:ser");
+                        stockChart.datas = ExtractChartData(serNodes);
+                        charts.Add(stockChart);
+                        break;
+                    case "surfaceChart":
+                    case "surface3DChart":
+                        SurfaceChart surfaceChart = new SurfaceChart { chartType = "surface" };
+                        if (key.Equals("surface3DChart"))
+                        {
+                            surfaceChart.is3D = true;
+                        }
+                        surfaceChart.surfaceType = key;
+                        var Wireframe = child.GetTextByPath("c:wireframe");
+                        if (Wireframe != null)
+                        {
+                            surfaceChart.surfaceType += "-" + Wireframe.Attribute("val").Value;
+                        }
+                        serNodes = child.GetTextByPathList("c:ser");
+                        surfaceChart.datas = ExtractChartData(serNodes);
+                        charts.Add(surfaceChart);
+                        break;
+                }
+            }
+            return charts;
+        }
+
+        public   List<Dictionary<string, object>> ExtractChartData(IEnumerable<XElement> nodes)
+        {
+
+            if (nodes != null)
+            {
+                List<Dictionary<string, object>> listDict = new List<Dictionary<string, object>>();
+                foreach (XElement node in nodes)
+                {
+
+                    if (node.GetTextByPath("c:xVal") != null)
+                    {
+                        Dictionary<string, object> dict = new Dictionary<string, object>();
+                        var xCvNodes = node.GetTextByPathList("c:xVal/c:numRef/c:numCache/c:pt/c:v");
+                        if (xCvNodes != null)
+                        {
+                            List<string> list = new List<string>();
+                            foreach (XElement cvNode in xCvNodes)
+                            {
+                                list.Add(cvNode.Value);
+                            }
+                            dict.Add("xAxis", list);
+                        }
+                        var yCvNodes = node.GetTextByPathList("c:yVal/c:numRef/c:numCache/c:pt/c:v");
+                        if (yCvNodes != null)
+                        {
+                            List<string> list = new List<string>();
+                            foreach (XElement cvNode in yCvNodes)
+                            {
+                                list.Add(cvNode.Value);
+                            }
+                            dict.Add("yAxis", list);
+                        }
+                        dict.Add("colName", "-");
+                        listDict.Add(dict);
+                    }
+                    else
+                    {
+                        Dictionary<string, object> dict = new Dictionary<string, object>();
+                        var spPr = node.GetTextByPath("c:spPr");
+                        if (spPr != null)
+                        {
+                            var ChartShapeProperties = new ChartShapeProperties(spPr.ToString());
+                            ShapeStyle shapeStyle = PPTXHelper.DoShapeProperties(ChartShapeProperties, slide, type, partForm);
+                            dict.Add("colStyle", shapeStyle);
+                        }
+                        else {
+                            dict.Add("colStyle", null);
+                        }
+                        var colNameNode = node.GetTextByPath("c:tx/c:strRef/c:strCache/c:pt/c:v");
+                        if (colNameNode != null)
+                        {
+                            dict.Add("colName", colNameNode.Value);
+                           
+                        }
+                        //name
+                        var catNodes = node.GetTextByPathList("c:cat/c:strRef/c:strCache/c:pt/c:v");
+                        if (catNodes == null)
+                        {
+                            catNodes = node.GetTextByPathList("c:cat/c:numRef/c:numCache/c:pt/c:v");
+                        }
+                        if (catNodes != null)
+                        {
+                            List<string> list = new List<string>();
+                            foreach (XElement cvNode in catNodes)
+                            {
+                                list.Add(cvNode.Value);
+                            }
+                            dict.Add("xAxis", list);
+                        }
+                        //value
+                        var valNodes = node.GetTextByPathList("c:val/c:numRef/c:numCache/c:pt/c:v");
+                        if (valNodes != null)
+                        {
+                            List<string> list = new List<string>();
+                            foreach (XElement cvNode in valNodes)
+                            {
+                                list.Add(cvNode.Value);
+                            }
+                            dict.Add("yAxis", list);
+                        }
+                        listDict.Add(dict);
+                    }
+                }
+                return listDict;
+            }
+            return null;
+        }
+
+        public void DoStyleEntry(DocumentFormat.OpenXml.Office2013.Drawing.ChartStyle.StyleEntry StyleEntry)
+        {
+            //TODO
+            /*
+          * LineReference
+            LineWidthScale
+            FillReference
+            EffectReference
+            FontReference
+            ShapeProperties
+            TextCharacterPropertiesType
+            TextBodyProperties
+            OfficeArtExtensionList
+          * */
+            var LineReference =  StyleEntry.LineReference;
+            var LineWidthScale=  StyleEntry.LineWidthScale;
+            var FillReference=   StyleEntry.FillReference;
+            var EffectReference = StyleEntry.EffectReference;
+            var FontReference= StyleEntry.FontReference;
+            var ShapeProperties = StyleEntry.ShapeProperties;
+            var TextCharacterPropertiesType = StyleEntry.TextCharacterPropertiesType;
+            var TextBodyProperties = StyleEntry.TextBodyProperties;
+            var OfficeArtExtensionList = StyleEntry.OfficeArtExtensionList;
+        }
+    }
+
+   
+    public class ChartStyle { 
+    //
+
+    }
+}

+ 65 - 0
HTEXLib/Models/HTEX/HtexDiagram.cs

@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace HTEXLib.Models.HTEX
+{
+    public class HtexDiagram : HtexElement
+    {
+        public HtexDiagram(string id, double rot, double width, double height,
+                                 double top, double left, bool invisible,
+                                 bool animatable, int index, DocumentFormat.OpenXml.Drawing.Diagrams.RelationshipIds Diagram, PPTSlide slide, string partForm)
+        {
+            base.slide = slide;
+            this.rot = rot;
+            this.Diagram = Diagram;
+            base.id = id;
+            base.top = top;
+            base.left = left;
+            base.width = width;
+            base.height = height;
+            base.invisible = invisible;
+            base.animatable = animatable;
+            base.index = index;
+            base.type = "Diagram";
+            base.partForm = partForm;
+        }
+        public DocumentFormat.OpenXml.Drawing.Diagrams.RelationshipIds Diagram { get; set; }
+        public override List<Item> DrawElement()
+        {
+            DoDiagram();
+            return null; 
+        }
+
+        private void DoDiagram()
+        {
+            //datapart r:dm="rId2" layoutpart r:lo="rId3"  stylepart r:qs="rId4" colorpart r:cs="rId5" />
+            var DataPart = Diagram.DataPart.Value;
+            var LayoutPart = Diagram.LayoutPart.Value;
+            var StylePart = Diagram.StylePart.Value;
+            var ColorPart = Diagram.ColorPart.Value;
+            var Data = slide.SlidePart.Parts.Where(x => x.RelationshipId == DataPart).FirstOrDefault();
+            var Layout = slide.SlidePart.Parts.Where(x => x.RelationshipId == LayoutPart).FirstOrDefault();
+            var Style = slide.SlidePart.Parts.Where(x => x.RelationshipId == StylePart).FirstOrDefault();
+            var Color = slide.SlidePart.Parts.Where(x => x.RelationshipId == ColorPart).FirstOrDefault();
+
+            if (Layout != null)
+            {
+                var url = Layout.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
+            }
+            if (Style != null)
+            {
+                var url = Style.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
+            }
+            if (Color != null)
+            {
+                var url = Color.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
+            }
+            if (Data != null)
+            {
+                var url = Data.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
+            }
+        }
+    }
+}

+ 17 - 35
HTEXLib/Models/HTEX/HtexGraphicFrame.cs

@@ -1,6 +1,13 @@
+using DocumentFormat.OpenXml;
+using DocumentFormat.OpenXml.Drawing;
 using DocumentFormat.OpenXml.Drawing.Diagrams;
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Presentation;
+using HTEXLib.Helpers.ShapeHelpers;
+using HTEXLib.Models.Inner;
 using System;
 using System.Collections.Generic;
+using System.Drawing;
 using System.Linq;
 using System.Text;
 
@@ -32,53 +39,28 @@ namespace HTEXLib.Models.HTEX
         public override List<Item> DrawElement()
         {
             var GraphicDataChildren = graphicFrame.element.Graphic.GraphicData.ChildElements;
+            
             foreach (var clild in GraphicDataChildren) {
                 if (clild is DocumentFormat.OpenXml.Drawing.Table Table) {
-                    var tal = Table;
+                    HtexTable table = new HtexTable(id,rot,width,height,top,left,invisible,animatable,index,Table,slide,partForm);
+                    return table.DrawElement();
                 }
                 if (clild is DocumentFormat.OpenXml.Drawing.Charts.ChartReference Chart)
                 {
-                    var ChartNode = slide.SlidePart.Parts.Where(x => x.RelationshipId == Chart.Id).FirstOrDefault();
-                    var url = ChartNode.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
+                    HtexChart chart = new HtexChart(id, rot, width, height, top, left, invisible, animatable, index, Chart, slide, partForm);
+                    return chart.DrawElement();
                 }
                 if (clild is DocumentFormat.OpenXml.Drawing.Diagrams.RelationshipIds Diagram)
                 {
-                  
-                    DoDiagram(Diagram);
-                    
+                    HtexDiagram diagram = new HtexDiagram(id, rot, width, height, top, left, invisible, animatable, index, Diagram, slide, partForm);
+                    return diagram.DrawElement();
                 }
             }
             return null; 
         }
+        
 
-        private void DoDiagram(RelationshipIds Diagram)
-        { 
-            //datapart r:dm="rId2" layoutpart r:lo="rId3"  stylepart r:qs="rId4" colorpart r:cs="rId5" />
-            var DataPart = Diagram.DataPart.Value;
-            var LayoutPart = Diagram.LayoutPart.Value;
-            var StylePart = Diagram.StylePart.Value;
-            var ColorPart = Diagram.ColorPart.Value;
-            var Data = slide.SlidePart.Parts.Where(x => x.RelationshipId == DataPart).FirstOrDefault();
-            var Layout = slide.SlidePart.Parts.Where(x => x.RelationshipId == LayoutPart).FirstOrDefault();
-            var Style = slide.SlidePart.Parts.Where(x => x.RelationshipId == StylePart).FirstOrDefault();
-            var Color = slide.SlidePart.Parts.Where(x => x.RelationshipId == ColorPart).FirstOrDefault();
-
-            if (Layout != null)
-            {
-                var url = Layout.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
-            }
-            if (Style != null)
-            {
-                var url = Style.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
-            }
-            if (Color != null)
-            {
-                var url = Color.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
-            }
-            if (Data != null)
-            {
-                var url = Data.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
-            }
-        }
+        
+       
     }
 }

+ 6 - 3
HTEXLib/Models/HTEX/HtexShape.cs

@@ -48,7 +48,7 @@ namespace HTEXLib.Models.HTEX
             var shapeTypeNode = Shape.element.ShapeProperties.GetFirstChild<PresetGeometry>();
             var shapeTypeCustom = Shape.element.ShapeProperties.GetFirstChild<CustomGeometry>();
 
-            var shapeType = shapeTypeNode.Preset.InnerText;
+            
             SlideColor slideColor = PPTXHelper.DoShapeStyle(Shape.element.ShapeStyle, slide,type);
             //从ShapeProperties 获取 p:spPr
             //再从 ShapeStyle 获取 p:spPr
@@ -75,7 +75,8 @@ namespace HTEXLib.Models.HTEX
                 shape.fill = ShapeStyle.fill;
             }
 
-            if (shapeTypeNode != null&& !string.IsNullOrEmpty(shapeType)) {
+            if (shapeTypeNode != null && shapeTypeNode.Preset!=null  && !string.IsNullOrEmpty(shapeTypeNode.Preset.InnerText)) {
+                var shapeType = shapeTypeNode.Preset.InnerText;
                 Svg svg = PPTXSvg.GenShapeSvg(Shape.element, index, shapeType, position, shape.border);
                 shape.svg = svg;
                 shape.shapeType = shapeType;
@@ -200,7 +201,9 @@ namespace HTEXLib.Models.HTEX
                     newTop = font.Height;
                 }
                 List<HtexText> processedElements = new List<HtexText>();
-                foreach (var text in breakTextsToShape(par)) {
+                IEnumerable<PPTRunProperties> pPTRunProperties = breakTextsToShape(par);
+                foreach (var text in pPTRunProperties)
+                {
                     float points = float.Parse(text.FontSize.ToString()) * 72.0F / 96.0F;
                     Font font = new System.Drawing.Font(text.FontFamily.ToString(), points);
                     if (text.Bold) font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Bold);

+ 0 - 4
HTEXLib/Models/HTEX/HtexSlide.cs

@@ -58,10 +58,6 @@ namespace HTEXLib.Models.HTEX
             bool animatable = baseShape.Animatable;
             string clickLinkUrl = baseShape.ClickLinkUrl;
 
-            
-
-
-
             if (baseShape is PPTGraphicFrame graphicFrame)
             {
                 HtexGraphicFrame htmlSmartArt = new HtexGraphicFrame(Id, rot, width, height, top,

+ 443 - 0
HTEXLib/Models/HTEX/HtexTable.cs

@@ -0,0 +1,443 @@
+using DocumentFormat.OpenXml;
+using DocumentFormat.OpenXml.Drawing;
+using DocumentFormat.OpenXml.Drawing.Diagrams;
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Presentation;
+using HTEXLib.Helpers.ShapeHelpers;
+using HTEXLib.Models.Inner;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+
+namespace HTEXLib.Models.HTEX
+{
+    public class HtexTable: HtexElement
+    {
+        public HtexTable(string id, double rot, double width, double height,
+                               double top, double left, bool invisible,
+                               bool animatable, int index, DocumentFormat.OpenXml.Drawing.Table table, PPTSlide slide, string partForm) {
+            base.slide = slide;
+            this.rot = rot;
+            this.Table = table;
+            base.id = id;
+            base.top = top;
+            base.left = left;
+            base.width = width;
+            base.height = height;
+            base.invisible = invisible;
+            base.animatable = animatable;
+            base.index = index;
+            base.type = "Table";
+            base.partForm = partForm;
+        }
+        public override List<Item> DrawElement() {
+            Position position = new Position { cx = width, cy = height, x = left, y = top, rot = rot };
+            TbStyle tbStyle = PPTXHelper.DoTableProperties(Table.TableProperties, slide, type, partForm);
+            List<GridColumn> columns = Table.TableGrid.Elements<GridColumn>().ToList();
+            tbStyle.ColumnWidth = columns.Select(x => x.Width * Globals.px96 * 1.0 / Globals.px914400).ToList();
+            List<TableRow> rows = Table.Elements<TableRow>().ToList();
+            var trs = DoTableRow(rows, slide, type, partForm);
+            Table table = new Table() { tr = trs, style = tbStyle, position = position, type =type, index = index, animatable = animatable, invisible = invisible };
+            var elmt = new List<Item>();
+            elmt.Add(table);
+            return elmt;
+        }
+        public DocumentFormat.OpenXml.Drawing.Table Table { get; set; }
+        public List<Tr> DoTableRow(List<TableRow> rows, PPTSlide slide, string type, string partForm)
+        {
+            List<Tr> trs = new List<Tr>();
+            foreach (TableRow row in rows)
+            {
+                Tr tr = new Tr { height = row.Height };
+                var r = row.Elements<TableCell>();
+                foreach (TableCell cell in r)
+                {
+                    CellStyle cellStyle = PPTXHelper.DoTableCellProperties(cell.TableCellProperties, slide, type, partForm);
+                    Td td = new Td();
+                    if (cell != null)
+                    {
+                        if (cell.RowSpan != null)
+                        {
+                            td.rowspan = cell.RowSpan;
+                        }
+                        if (cell.GridSpan != null)
+                        {
+                            td.colspan = cell.GridSpan;
+                        }
+                        if (cell.HorizontalMerge != null)
+                        {
+                            td.hmerge = cell.HorizontalMerge;
+                        }
+                        if (cell.VerticalMerge != null)
+                        {
+                            td.vmerge = cell.VerticalMerge;
+                        }
+                    }
+                    td.style = cellStyle;
+                    LinkedList<PPTParagraph> PPTParagraphs = DoTextBody(cell.TextBody, slide.SlidePart, slide.shapeListStyleMaster, slide.shapeListStyleLayout);
+                    List<Paragraph> paragraphs = DrawText(PPTParagraphs);
+                    td.paragraphs = paragraphs;
+                    tr.td.Add(td);
+                }
+                trs.Add(tr);
+            }
+            return trs;
+        }
+
+        public List<Paragraph> DrawText(LinkedList<PPTParagraph> Texts)
+        {
+            List<Paragraph> Paragraphs = new List<Paragraph>();
+            foreach (var par in Texts)
+            {
+                double paragraphTop = par.getSpaceBeforePoints();
+                Paragraph paragraph = new HTEXLib.Paragraph { animatable = par.Animatable, invisible = par.Invisible };
+                int newTop = par.getSpaceBeforePoints();
+                int left = 0;
+                List<HtexText> textElements = new List<HtexText>();
+                if (par.RunPropList == null || par.RunPropList.Count == 0 && par.defaultRunProperties != null)  //Only paragraph!
+                {
+                    float points = float.Parse(par.defaultRunProperties.FontSize.ToString()) * 72.0F / 96.0F;
+                    System.Drawing.Font font = new System.Drawing.Font(par.defaultRunProperties.FontFamily.ToString(), points);
+                    newTop = font.Height;
+                }
+                List<HtexText> processedElements = new List<HtexText>();
+                IEnumerable<PPTRunProperties> pPTRunProperties = breakTextsToShape(par);
+                foreach (var text in pPTRunProperties)
+                {
+                    float points = float.Parse(text.FontSize.ToString()) * 72.0F / 96.0F;
+                    System.Drawing.Font font = new System.Drawing.Font(text.FontFamily.ToString(), points);
+                    if (text.Bold) font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Bold);
+                    else if (text.Italic)
+                        font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Italic);
+                    else if (text.Underline != null && text.Underline.Equals("Single"))
+                        font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Underline);
+                    newTop = font.Height > newTop ? font.Height : newTop;
+                    newTop = par.getLineSpacingInPointsFromFont(newTop);
+                    if (text.isBreak)
+                    {
+                        top += newTop;
+                        left = 0;
+                        fixLeftSpacingForAlignment(processedElements, par, font);
+                        processedElements.Clear();
+                        continue;
+                    }
+                    String currentString = text.Text.TrimEnd() + getStringFromTextElements(processedElements);
+                    HtexText t1 = new HtexText(left: left,
+                                            top: top,
+                                            fontFamily: text.FontFamily,
+                                            fontColor: text.FontColor,
+                                            fontSize: text.FontSize,
+                                            isBullet: text.isBullet,
+                                            bold: text.Bold,
+                                            italic: text.Italic,
+                                            underline: text.Underline,
+                                            id: id,
+                                            slideIndex: slide.slideIndex)
+                    {
+                        Rotate = this.rot
+                    };
+                    t1.width = MeasureString(text.Text, font);
+
+                    if (text.isBullet && text.Text != null && text.Text.Contains("rId"))
+                    {
+                        t1.PictureBullet = true;
+                        t1.width = text.bulletSize;
+                        t1.bulletSize = text.bulletSize;
+                        newTop = text.bulletSize;
+                    }
+                    t1.Text = text.Text;
+                    textElements.Add(t1);
+                    processedElements.Add(t1);
+                }
+                fixLeftSpacingForAlignment(processedElements, par);
+
+                HtexText lastTxt = null;
+                List<HtexText> mergedTextElements = new List<HtexText>();
+                foreach (HtexText textElement in textElements)
+                {
+                    if (lastTxt == null || !lastTxt.sameProps(textElement))
+                        mergedTextElements.Add(textElement);
+                    else
+                        mergedTextElements[mergedTextElements.Count - 1].Text += textElement.Text;
+
+                    lastTxt = textElement;
+                }
+
+                //foreach (HtexText textElement in mergedTextElements) {
+                // shapeBuilder.Append(textElement.DrawElement());
+                //}
+
+                top += newTop;
+                top += par.getSpaceAfterPoints(newTop);
+                top += par.getSpaceBeforePoints(newTop);
+                paragraph.texts = textElements;
+                Paragraphs.Add(paragraph);
+            }
+            return Paragraphs;
+        }
+        private String getStringFromTextElements(List<HtexText> elements)
+        {
+            if (elements == null || elements.Count == 0)
+                return "";
+            StringBuilder result = new StringBuilder();
+            foreach (HtexText el in elements)
+            {
+                result.Append(el.Text);
+            }
+            return result.ToString();
+        }
+        //We have two similar methods - this one is better because it measures the whole string with the font. 
+        private void fixLeftSpacingForAlignment(List<HtexText> textElements, PPTParagraph par, System.Drawing.Font font)
+        {
+            int combinedWidth = 0;
+
+            StringBuilder combinedText = new StringBuilder();
+            foreach (HtexText textElement in textElements)
+            {
+                if (textElement.PictureBullet)
+                    combinedWidth += textElement.bulletSize;
+                else
+                    combinedText.Append(textElement.Text);
+            }
+            int bulletOffset = 0;
+            if (par.bullet != null && textElements.Count > 0 && !textElements[0].isBullet)
+            {
+                bulletOffset = par.bullet.bulletSize;
+                combinedWidth += par.bullet.bulletSize;
+            }
+            combinedWidth += MeasureString(combinedText.ToString(), font);
+
+            double firstLeft = 0;
+            if ("Center".Equals(par.Align))
+                firstLeft = ((this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth) / 2;
+            else if ("Right".Equals(par.Align))
+                firstLeft = (this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth;
+            combinedText = new StringBuilder();
+            combinedWidth = 0; //Now used only for picture bullets!
+            foreach (HtexText textElement in textElements)
+            {
+                textElement.setLeft(firstLeft + par.Indent + bulletOffset + par.marginLeft + combinedWidth + MeasureString(combinedText.ToString(), font));
+                if (textElement.PictureBullet)
+                    combinedWidth += textElement.bulletSize;
+                else
+                    combinedText.Append(textElement.Text);
+            }
+        }
+        //We have two similar methods. This is worse because it uses the Width property of each element instead of measuring the whole string. 
+        //There is mistake in the calculations coming from that and the difference is bigger when there are more elements. 
+        private void fixLeftSpacingForAlignment(List<HtexText> textElements, PPTParagraph par)
+        {
+            int combinedWidth = 0;
+
+            foreach (HtexText textElement in textElements)
+                combinedWidth += textElement.width;
+            int bulletOffset = 0;
+            if (par.bullet != null && textElements.Count > 0 && !textElements[0].isBullet)
+            {
+                combinedWidth += par.bullet.bulletSize;
+                bulletOffset = par.bullet.bulletSize;
+            }
+
+            double currentLeft = 0;
+            if ("Center".Equals(par.Align))
+                currentLeft = ((this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth) / 2;
+            else if ("Right".Equals(par.Align))
+                currentLeft = (this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight) - combinedWidth;
+
+            foreach (HtexText textElement in textElements)
+            {
+                textElement.setLeft(currentLeft + par.Indent + bulletOffset + par.marginLeft);
+                currentLeft += textElement.width;
+            }
+        }
+        private IEnumerable<PPTRunProperties> breakTextsToShape(PPTParagraph par)
+        {
+            List<PPTRunProperties> list = par.RunPropList;
+            List<PPTRunProperties> result = new List<PPTRunProperties>();
+            String previousToken = null;
+            int bulletSize = 0;
+            foreach (var text in list)
+            {
+                float points = float.Parse(text.FontSize.ToString()) * 72.0F / 96.0F;
+                System.Drawing.Font font = new System.Drawing.Font(text.FontFamily.ToString(), points);
+                if (text.Bold) font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Bold);
+                else if (text.Italic) font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Italic);
+                else if (text.Underline != null && text.Underline.Equals("Single"))
+                    font = new System.Drawing.Font(text.FontFamily.ToString(), points, System.Drawing.FontStyle.Underline);
+
+                int size = 0;
+                if (text.isBullet && text.Text != null && text.Text.Contains("rId"))
+                    bulletSize = text.bulletSize;
+                else
+                    size = MeasureString((previousToken == null ? "" : previousToken + " ") + text.Text, font);
+                if (text.isBreak || size + bulletSize < this.width - par.Indent - par.marginLeft - par.marginRight)//- Shape.LeftInset - Shape.RightInset)
+                {
+                    if (text.Text != null && text.Text.Trim() != "" && !(text.isBullet && text.Text.Contains("rId")))
+                    {
+                        previousToken = (previousToken == null ? "" : previousToken) + text.Text;
+                    }
+                    if (text.isBreak)
+                        previousToken = null;
+                    result.Add(text);
+                    continue;
+                }
+
+                //   previousToken = null;
+
+                string[] tokens = text.Text.Split(' ');
+                int index = 0;
+                foreach (string token in tokens)
+                {
+                    index++;
+                    int combinedSize = MeasureString((previousToken == null ? "" : previousToken + " ") + token, font);
+
+                    if (combinedSize + bulletSize > this.width - par.Indent - par.marginLeft - par.marginRight)//- Shape.LeftInset - Shape.RightInset)
+                    {
+                        PPTRunProperties temp = new PPTRunProperties(text);
+                        temp.Text = "";
+                        temp.isBreak = true;
+                        result.Add(temp);
+
+                        temp = new PPTRunProperties(text);
+                        temp.Text = index < tokens.Length ? token + " " : token;
+                        result.Add(temp);
+                        previousToken = token;
+                    }
+                    else
+                    {
+                        PPTRunProperties temp = new PPTRunProperties(text);
+                        temp.Text = index < tokens.Length ? token + " " : token;
+                        result.Add(temp);
+                        previousToken = (previousToken == null ? "" : previousToken + " ") + token;
+                    }
+                }
+            }
+            return result;
+        }
+        public static int MeasureString(string s, System.Drawing.Font font)
+        {
+            s = s.Replace("\t", "aaaa");//TODO the replace is dirty hack for measuring tabulations
+
+            StringFormat stringFormat = new StringFormat(StringFormat.GenericTypographic);
+            CharacterRange[] rng = { new CharacterRange(0, s.Length) };
+            stringFormat.SetMeasurableCharacterRanges(rng);
+            Graphics g = Graphics.FromImage(new Bitmap(100, 100));
+            //Use measure character ranges with a big box because we used this for measurement only
+            //Later we might better use this for drawing the text. 
+            Region[] regions = g.MeasureCharacterRanges(s, font, new System.Drawing.Rectangle(0, 0, 10000, 3000), stringFormat);
+            foreach (Region region in regions)
+            {
+                RectangleF rect = region.GetBounds(g);
+                return (int)System.Math.Round(rect.Width);
+            }
+            return 0;
+
+            // 
+            //             SizeF result;
+            //             using (var image = new Bitmap(1, 1))
+            //             {
+            //                 using (var g = Graphics.FromImage(image))
+            //                 {
+            //                     result = g.MeasureString(s, font);
+            //                 }
+            //             }
+            // 
+            //             return result.ToSize();
+        }
+        public LinkedList<PPTParagraph> DoTextBody(DocumentFormat.OpenXml.Drawing.TextBody TextBody, OpenXmlPart slidePart, ListStyle shapeListStyleMaster, ListStyle shapeListStyleLayout)
+        {
+            LinkedList<PPTParagraph> Texts = new LinkedList<PPTParagraph>();
+            bool IsText = true;
+            int fontScale = 100000;
+            if (TextBody == null)
+            {
+                IsText = false;
+                return null;
+            }
+            if (TextBody.BodyProperties != null)
+            {
+                if (TextBody.BodyProperties.Anchor != null)
+                {
+                    DocumentFormat.OpenXml.Drawing.TextAnchoringTypeValues VerticalAlign = TextBody.BodyProperties.Anchor;
+                }
+                if (TextBody.BodyProperties.GetFirstChild<NormalAutoFit>() != null &&
+                  TextBody.BodyProperties.GetFirstChild<NormalAutoFit>().FontScale != null)
+                {
+                    fontScale = TextBody.BodyProperties.GetFirstChild<NormalAutoFit>().FontScale.Value;
+                }
+            }
+            int index = 0;
+
+            foreach (var paragraph in TextBody.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
+            {
+                PlaceholderShape placeholder = null;
+                var par = new PPTParagraph(slide, placeholder)
+                {
+                    Paragraph = index++
+                };
+
+                if (paragraph.ParagraphProperties != null)
+                {
+                    int level = paragraph.ParagraphProperties.Level == null ?
+                               -1 : paragraph.ParagraphProperties.Level.Value;
+                    par.Level = level;
+                }
+
+                par.SetParagraphProperties(paragraph, slidePart,
+                                           shapeListStyleMaster, shapeListStyleLayout);
+                bool hasText = false;
+                foreach (var obj in paragraph.ChildElements)
+                {
+                    hasText = GetParagraphChildElements(TextBody, par, hasText, obj, fontScale);
+                }
+                //This is because when we set paragraph properties we add the bullet to the text runs.
+                //If we don't have text it still outputs the bullet character. 
+                if (par.bullet != null && hasText)
+                {
+                    par.RunPropList.Insert(0, par.bullet);
+                }
+                Texts.AddLast(par);
+            }
+            return Texts;
+        }
+
+        private bool GetParagraphChildElements(DocumentFormat.OpenXml.Drawing.TextBody shape, PPTParagraph par, bool hasText, OpenXmlElement obj, int fontScale)
+        {
+            LinkedList<string> effectShapes = new LinkedList<string>();
+            if (obj is Run)
+            {
+                Run run = (Run)obj;
+                hasText = true;
+                PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
+                runProp.Text = run.Text.Text;
+                runProp.SetRunProperties(run.RunProperties, shape, ref effectShapes);
+                runProp.FontSize = System.Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
+                par.RunPropList.Add(runProp);
+            }
+
+            else if (obj is Field)
+            {
+                Field run = (Field)obj;
+                hasText = true;
+                PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
+                runProp.Text = run.Text.Text;
+                runProp.SetRunProperties(run.RunProperties, shape, ref effectShapes);
+                runProp.FontSize = System.Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
+                par.RunPropList.Add(runProp);
+            }
+
+            else if (obj is Break)
+            {
+                Break aBreak = (Break)obj;
+                PPTRunProperties runProp = new PPTRunProperties(par.defaultRunProperties);
+                runProp.SetRunProperties(aBreak.RunProperties, shape, ref effectShapes);
+                runProp.FontSize = System.Math.Round(fontScale * runProp.FontSize / Globals.PercentageConstant);
+                runProp.isBreak = true;
+                par.RunPropList.Add(runProp);
+            }
+            return hasText;
+        }
+    }
+}

+ 2 - 1
HTEXLib/Models/PPTX/PPTAlternateContent.cs

@@ -1,5 +1,6 @@
 using DocumentFormat.OpenXml;
 using DocumentFormat.OpenXml.Packaging;
+using HTEXLib.Helpers.ShapeHelpers;
 using System;
 using System.Collections.Generic;
 using System.Text;
@@ -10,7 +11,7 @@ namespace HTEXLib.Models.Inner
     {
         public PPTAlternateContent(SlidePart slidePart, AlternateContent alternateContent, PPTSlide slide)
         {
-            
+            suid = ShaHashHelper.GetSHA1((alternateContent.GetType().Name + alternateContent.OuterXml).Trim().ToLower());
             SetAlternateContentVisualProperties(slidePart, alternateContent);
             SetAlternateContentNonVisualProperties(slidePart, alternateContent);
 

+ 3 - 0
HTEXLib/Models/PPTX/PPTConnectionShape.cs

@@ -5,12 +5,15 @@ using System.Text;
 using System.Threading.Tasks;
 using DocumentFormat.OpenXml.Packaging;
 using DocumentFormat.OpenXml.Presentation;
+using HTEXLib.Helpers.ShapeHelpers;
+
 namespace HTEXLib.Models.Inner
 {
     public class PPTConnectionShape : PPTShapeBase
     {
         public PPTConnectionShape(OpenXmlPart openXmlPart, ConnectionShape connectionShape)
         {
+            suid = ShaHashHelper.GetSHA1((connectionShape.GetType().Name + connectionShape.OuterXml).Trim().ToLower());
             if (openXmlPart is SlidePart slidePart)
             {
                 PartForm = "slide";

+ 2 - 0
HTEXLib/Models/PPTX/PPTGraphicFrame.cs

@@ -1,5 +1,6 @@
 using DocumentFormat.OpenXml.Packaging;
 using DocumentFormat.OpenXml.Presentation;
+using HTEXLib.Helpers.ShapeHelpers;
 
 namespace HTEXLib.Models.Inner
 {
@@ -8,6 +9,7 @@ namespace HTEXLib.Models.Inner
         public DocumentFormat.OpenXml.Presentation.GraphicFrame element { get; set; }
         public PPTGraphicFrame(OpenXmlPart openXmlPart, GraphicFrame gfarame)
         {
+            suid = ShaHashHelper.GetSHA1((gfarame.GetType().Name + gfarame.OuterXml).Trim().ToLower());
             if (openXmlPart is SlidePart slidePart)
             {
                 PartForm = "slide";

+ 2 - 0
HTEXLib/Models/PPTX/PPTGroupShape.cs

@@ -7,6 +7,7 @@ using DocumentFormat.OpenXml;
 using DocumentFormat.OpenXml.Drawing;
 using DocumentFormat.OpenXml.Packaging;
 using DocumentFormat.OpenXml.Presentation;
+using HTEXLib.Helpers.ShapeHelpers;
 
 namespace HTEXLib.Models.Inner
 {
@@ -14,6 +15,7 @@ namespace HTEXLib.Models.Inner
     {
         public PPTGroupShape(OpenXmlPart openXmlPart, DocumentFormat.OpenXml.Presentation.GroupShape groupShape ,PPTSlide slide)
         {
+            suid = ShaHashHelper.GetSHA1((groupShape.GetType().Name + groupShape.OuterXml).Trim().ToLower());
             if (openXmlPart is SlidePart slidePart)
             {
                 PartForm = "slide";

+ 2 - 0
HTEXLib/Models/PPTX/PPTImage.cs

@@ -1,5 +1,6 @@
 using DocumentFormat.OpenXml.Packaging;
 using DocumentFormat.OpenXml.Presentation;
+using HTEXLib.Helpers.ShapeHelpers;
 using System;
 namespace HTEXLib.Models.Inner
 {
@@ -7,6 +8,7 @@ namespace HTEXLib.Models.Inner
     {
         public PPTImage(OpenXmlPart openXmlPart, Picture picture)
         {
+            suid = ShaHashHelper.GetSHA1((picture.GetType().Name + picture.OuterXml).Trim().ToLower());
             if (openXmlPart is SlidePart slidePart)
             {
                 PartForm = "slide";

+ 141 - 0
HTEXLib/Models/PPTX/PPTRunProperties.cs

@@ -5,6 +5,7 @@ using System.Text;
 using System.Threading.Tasks;
 using DocumentFormat.OpenXml;
 using DocumentFormat.OpenXml.Drawing;
+using DocumentFormat.OpenXml.Drawing.Charts;
 using DocumentFormat.OpenXml.Packaging;
 using DocumentFormat.OpenXml.Presentation;
 
@@ -61,6 +62,8 @@ namespace HTEXLib.Models.Inner
             this.slide = copy.slide;
         }
 
+
+
         public void SetRunProperties(RunProperties runProperties,
                      DocumentFormat.OpenXml.Presentation.Shape shape,
                      ref LinkedList<string> effectShapes)
@@ -79,6 +82,144 @@ namespace HTEXLib.Models.Inner
                 }
 
 
+                //get the text color.
+                var solidFill = runProperties.GetFirstChild<SolidFill>();
+                if (solidFill != null)
+                {
+                    this.ReadSolidFillColors(solidFill);
+                }
+                if (runProperties.FontSize != null)
+                {
+                    FontSize = runProperties.FontSize / Globals.FontPoint;
+                }
+                if (runProperties.Bold != null)
+                {
+                    Bold = runProperties.Bold;
+                }
+
+                if (runProperties.Italic != null)
+                {
+                    Italic = runProperties.Italic;
+                }
+                if (runProperties.Underline != null)
+                {
+                    Underline = runProperties.Underline.Value.ToString();
+                }
+                if (runProperties.Spacing != null)
+                {
+                    Spacing = runProperties.Spacing.Value;
+                }
+
+                var coplexScriptFonts = runProperties.Descendants<ComplexScriptFont>();
+                var latinFonts = runProperties.GetFirstChild<LatinFont>();
+                var EastAsianFont = runProperties.GetFirstChild<EastAsianFont>();
+                var ComplexScriptFont = runProperties.GetFirstChild<ComplexScriptFont>();
+                if (EastAsianFont != null)
+                {
+                    this.ReadFontFamilyFromTheme(EastAsianFont);
+                }
+                if (ComplexScriptFont != null)
+                {
+                    this.ReadFontFamilyFromTheme(ComplexScriptFont);
+                }
+                if (latinFonts != null)
+                {
+                    this.ReadFontFamilyFromTheme(latinFonts);
+                }
+                else if (coplexScriptFonts.GetEnumerator().Current != null)
+                {
+                    FontFamily = coplexScriptFonts.GetEnumerator().Current.Typeface;
+                }
+            }
+        }
+        public void SetRunProperties(RunProperties runProperties,
+                   //  DocumentFormat.OpenXml.Presentation.Shape shape,
+                   DocumentFormat.OpenXml.Drawing.TextBody TextBody,
+                     ref LinkedList<string> effectShapes)
+        {
+            if (runProperties != null)
+            {
+                EffectList effects = runProperties.GetFirstChild<EffectList>();
+                GradientFill gradient = runProperties.GetFirstChild<GradientFill>();
+
+                if ((TextBody.BodyProperties != null && TextBody.BodyProperties.FromWordArt != null && TextBody.BodyProperties.FromWordArt) ||
+                    (effects != null && effects.HasChildren) ||
+                    (gradient != null && gradient.HasChildren))
+                {
+                    //UInt32Value id = shape.NonVisualShapeProperties.NonVisualDrawingProperties.Id;
+                    effectShapes.AddLast(slide.slideIndex + "_" + 0);
+                }
+
+
+                //get the text color.
+                var solidFill = runProperties.GetFirstChild<SolidFill>();
+                if (solidFill != null)
+                {
+                    this.ReadSolidFillColors(solidFill);
+                }
+                if (runProperties.FontSize != null)
+                {
+                    FontSize = runProperties.FontSize / Globals.FontPoint;
+                }
+                if (runProperties.Bold != null)
+                {
+                    Bold = runProperties.Bold;
+                }
+
+                if (runProperties.Italic != null)
+                {
+                    Italic = runProperties.Italic;
+                }
+                if (runProperties.Underline != null)
+                {
+                    Underline = runProperties.Underline.Value.ToString();
+                }
+                if (runProperties.Spacing != null)
+                {
+                    Spacing = runProperties.Spacing.Value;
+                }
+
+                var coplexScriptFonts = runProperties.Descendants<ComplexScriptFont>();
+                var latinFonts = runProperties.GetFirstChild<LatinFont>();
+                var EastAsianFont = runProperties.GetFirstChild<EastAsianFont>();
+                var ComplexScriptFont = runProperties.GetFirstChild<ComplexScriptFont>();
+                if (EastAsianFont != null)
+                {
+                    this.ReadFontFamilyFromTheme(EastAsianFont);
+                }
+                if (ComplexScriptFont != null)
+                {
+                    this.ReadFontFamilyFromTheme(ComplexScriptFont);
+                }
+                if (latinFonts != null)
+                {
+                    this.ReadFontFamilyFromTheme(latinFonts);
+                }
+                else if (coplexScriptFonts.GetEnumerator().Current != null)
+                {
+                    FontFamily = coplexScriptFonts.GetEnumerator().Current.Typeface;
+                }
+            }
+        }
+        public void SetRunProperties(RunProperties runProperties,
+                  //  DocumentFormat.OpenXml.Presentation.Shape shape,
+                  RichText TextBody,
+                    ref LinkedList<string> effectShapes)
+        {
+            if (runProperties != null)
+            {
+                EffectList effects = runProperties.GetFirstChild<EffectList>();
+                GradientFill gradient = runProperties.GetFirstChild<GradientFill>();
+
+                if ((TextBody.BodyProperties != null && TextBody.BodyProperties.FromWordArt != null && TextBody.BodyProperties.FromWordArt) ||
+                    (effects != null && effects.HasChildren) ||
+                    (gradient != null && gradient.HasChildren))
+                {
+                    //UInt32Value id = shape.NonVisualShapeProperties.NonVisualDrawingProperties.Id;
+                    effectShapes.AddLast(slide.slideIndex + "_" + 0);
+                }
+
+
                 //get the text color.
                 var solidFill = runProperties.GetFirstChild<SolidFill>();
                 if (solidFill != null)

+ 4 - 1
HTEXLib/Models/PPTX/PPTShape.cs

@@ -12,6 +12,8 @@ using System.Drawing;
 using System.Drawing.Drawing2D;
 using System.Drawing.Imaging;
 using System.IO;
+using HTEXLib.Helpers.ShapeHelpers;
+
 namespace HTEXLib.Models.Inner
 {
     public class PPTShape : PPTShapeBase
@@ -23,7 +25,7 @@ namespace HTEXLib.Models.Inner
 
         public Boolean IsText { get; set; }
       
-        private PlaceholderShape placeholder;
+        private PlaceholderShape placeholder { get; set; }
 
         // Create a new linked list of strings.
         public LinkedList<PPTParagraph> Texts = new LinkedList<PPTParagraph>();
@@ -35,6 +37,7 @@ namespace HTEXLib.Models.Inner
 
         public PPTShape(OpenXmlPart openXmlPart, DocumentFormat.OpenXml.Presentation.Shape shape, PPTSlide slide) : base()
         {
+            suid =ShaHashHelper.GetSHA1((shape.GetType().Name + shape.OuterXml).Trim().ToLower());
             if (openXmlPart is SlidePart slidePart)
             {
                 PartForm = "slide";

+ 2 - 0
HTEXLib/Models/PPTX/PPTShapeBase.cs

@@ -11,6 +11,7 @@ namespace HTEXLib.Models.Inner
 {
     public class PPTShapeBase
     {
+        public string suid { get; set; }
         public PPTVisualPPTShapeProp VisualShapeProp { get; set; }
         public PPTNonVisualShapeProp NonVisualShapeProp { get; set; }
         public bool Invisible { get; set; }
@@ -21,6 +22,7 @@ namespace HTEXLib.Models.Inner
         public DocumentFormat.OpenXml.Drawing.ListStyle shapeListStyleLayout { get; set; }
         public DocumentFormat.OpenXml.Drawing.TextAnchoringTypeValues VerticalAlign { get; set; }
         public DocumentFormat.OpenXml.Packaging.OpenXmlPart SlidePart { get; set; }
+        public TableStylesPart tableStylesPart { get; set; }
         public int fontScale { get; set; } = 100000;
         public double BottomInset { get; set; }
         public double TopInset { get; set; }

+ 2 - 1
HTEXLib/Models/PPTX/PPTSlide.cs

@@ -13,8 +13,9 @@ namespace HTEXLib.Models
 {
     public class PPTSlide:PPTShapeBase
     {
-        public PPTSlide(SlidePart openXmlPart, int slideIndex, DefaultTextStyle defaultTextStyle,SlideSize SlideSizes, SlideMasterPart slideMasterPart, XElement root,IEnumerable<XElement> media)
+        public PPTSlide(SlidePart openXmlPart, int slideIndex, DefaultTextStyle defaultTextStyle,SlideSize SlideSizes, SlideMasterPart slideMasterPart, XElement root,IEnumerable<XElement> media,TableStylesPart tableStylesPart)
         {
+            base.tableStylesPart = tableStylesPart;
             base.SlidePart = openXmlPart;
             base.slideMasterPart = slideMasterPart;
             base.Root = root;

+ 93 - 18
HTEXLib/Models/Table.cs

@@ -4,19 +4,19 @@ using System.Text;
 
 namespace HTEXLib
 {
-    public class Table :Item
+    public class Table : Item
     {
+       
+        public TbStyle style { get; set; }
         public Table() {
             tr = new List<Tr>();
         }
         //内容排版方向 左书写 右书写
-        public string dir { get; set; }
-        public string collapse { get; set; } = "collapse";
-       // public Border Border { get; set; }
-       // public Fill Fill { get; set; }
+        // public Border Border { get; set; }
+        // public Fill Fill { get; set; }
         public List<Tr> tr { get; set; }
 
-       
+
     }
 
     public class Tr {
@@ -24,24 +24,99 @@ namespace HTEXLib
         {
             td = new List<Td>();
         }
-       
-        public Fill fill { get; set; }
-        public  double height { get; set; }
+
+       // public Fill fill { get; set; }
+        public double height { get; set; }
         public List<Td> td { get; set; }
-    
-        public List<Border> borders { get; set; }
+
+        //public List<Border> borders { get; set; }
     }
     public class Td
     {
         public double width { get; set; }
-    
-        public Fill fill { get; set; }
-        public int rowspan { get; set; }
-        public int colspan { get; set; }
 
-        public int vmerge { get; set; }
-        public int hmerge { get; set; }
+     //   public Fill fill { get; set; }
+        public CellStyle style { get; set; }
+        public int? rowspan { get; set; }
+        public int? colspan { get; set; }
+
+        public bool vmerge { get; set; }
+        public bool hmerge { get; set; }
         public List<Paragraph> paragraphs { get; set; }
-      
+
+    }
+
+    public class TbStyle { 
+        public Boolean RightToLeft { get; set; }
+        public Boolean FirstRow { get; set; }
+        public Boolean FirstColumn { get; set; }
+        public Boolean LastRow { get; set; }
+        public Boolean LastColumn { get; set; }
+        public Boolean BandRow { get; set; }
+        public Boolean BandColumn { get; set; }
+        public List<double> ColumnWidth { get; set; }
+        public List<CellStyle> cellStyles { get; set; }
+        public Fill fill { get; set; }
+    }
+    public class CellStyle { 
+        /// <summary>
+        /// 单元格边框样式
+        /// </summary>
+        public List<CellBorder> cellBorders { get; set; }
+        /// <summary>
+        /// 单元格填充样式
+        /// </summary>
+        public Fill fill { get; set; }
+        /// <summary>
+        /// 单元格字体样式
+        /// </summary>
+        public FontStyle fontStyle { get; set; }
+        public string type { get; set; }
+    }
+
+    /// <summary>
+    ///可以被叠加
+    /// </summary>
+    public class CellBorder {
+        /// <summary>
+        ///  Left 左边框 Right 右边框 Bottom 下边框 上边框 Top InHor 内部横线框 InVer 内部竖线框 Tl2br 从左上到右下斜线 Tr2bl 从右上到左下斜线
+        /// </summary>
+        public string  type { get; set; }
+        public Border border { get; set; }
+
+
+        /// <summary>
+        /// 左边框
+        /// </summary>
+      //  public Border Left { get; set; }
+        /// <summary>
+        /// 右边框
+        /// </summary>
+      //  public Border Right { get; set; }
+        /// <summary>
+        /// 下边框
+        /// </summary>
+       // public Border Bottom { get; set; }
+        /// <summary>
+        /// 上边框
+        /// </summary>
+      //  public Border Top { get; set; }
+        /// <summary>
+        /// 内部水平方向 内部横线框
+        /// </summary>
+       // public Border InHor { get; set; }
+        /// <summary>
+        /// 内部垂直方向 内部竖线框
+        /// </summary>
+       // public Border InVer { get; set; }
+        /// <summary>
+        /// 左上到下右边框  从左上到右下斜线
+        /// </summary>
+       // public Border Tl2br { get; set; }
+        /// <summary>
+        /// 右上到下左边的框 从右上到左下斜线
+        /// </summary>
+     //   public Border Tr2bl { get; set; }
     }
 }
+

Dosya farkı çok büyük olduğundan ihmal edildi
+ 3822 - 0
HTEXTest/MML2OMML.XSL


Dosya farkı çok büyük olduğundan ihmal edildi
+ 2068 - 0
HTEXTest/OMML2MML.XSL


+ 4 - 1
HTEXTest/Program.cs

@@ -1,3 +1,4 @@
+using DocumentFormat.OpenXml.Drawing;
 using HTEXLib;
 using HTEXLib.Builders;
 using HTEXLib.Controller;
@@ -10,7 +11,9 @@ namespace HTEXTest
     {
         static void Main(string[] args)
         {
-            string path = "F:\\PRD-20191015001-template.pptx";
+            //<a:schemeClr val="dk1" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" />
+           //  RgbColorModelHex rgbColorModelHex = new RgbColorModelHex(" <a:prstClr val=\"black\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"  />");
+            string path = "F:\\PRD-20191015001-template-math.pptx";
            // string path = "F:\\PRD-20191015001.pptx";
             var htexBuilder = new HtexBuilder();
             var pptSlides = htexBuilder.GetPPTSlides(path);

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 37735
HTEXTest/outppt.xml