Ver Fonte

SlideLayoutPart 存档

CrazyIter há 4 anos atrás
pai
commit
2673f15eb7

+ 6 - 6
HTEXLib/Animations/MotionPathAnimation.cs

@@ -19,13 +19,13 @@ namespace HTEXLib.Animations
             {
                 return 1;
             }
-            else if (SlideSizes.Cx < Globals.px12700)
+            else if (SlideSizes.Cx < Globals.px914400)
             {
-                return Globals.px12700*1.0  / SlideSizes.Cx;
+                return Globals.px914400*1.0  / SlideSizes.Cx * Globals.px96;
             }
             else
             {
-                return SlideSizes.Cx *1.0/ Globals.px12700;
+                return SlideSizes.Cx *1.0 * Globals.px96 / Globals.px914400;
             }
         }
 
@@ -35,13 +35,13 @@ namespace HTEXLib.Animations
             {
                 return 1;
             }
-            else if (SlideSizes.Cy < Globals.px12700)
+            else if (SlideSizes.Cy < Globals.px914400)
             {
-                return  Globals.px12700*1.0 / SlideSizes.Cy;
+                return  Globals.px914400*1.0 / SlideSizes.Cy * Globals.px96;
             }
             else
             {
-                return SlideSizes.Cy *1.0 / Globals.px12700;
+                return SlideSizes.Cy *1.0 * Globals.px96 / Globals.px914400;
             }
         }
         public MotionPathAnimation(CommonTimeNode commonTimeNode, int slideIndex, SlideSize SlideSizes)

+ 19 - 17
HTEXLib/Builders/HtexBuilder.cs

@@ -15,6 +15,7 @@ namespace HTEXLib.Builders
 {
     public class HtexBuilder
     {
+        public PresentationDocument presentationDocument { get; set; } = null;
         public bool online { get; set; }
         public string path { get; set; }
         public string upload { get; set; }
@@ -28,13 +29,13 @@ namespace HTEXLib.Builders
             {
                 return 1;
             }
-            else if (SlideSizes.Cx < Globals.px12700)
+            else if (SlideSizes.Cx < Globals.px914400)
             {
-                return Globals.px12700  *1.0/ SlideSizes.Cx ;
+                return Globals.px914400  *1.0/ SlideSizes.Cx *Globals.px96;
             }
             else
             {
-                return SlideSizes.Cx*1.0 / Globals.px12700;
+                return SlideSizes.Cx*1.0 * Globals.px96 / Globals.px914400;
             }
         }
 
@@ -44,24 +45,24 @@ namespace HTEXLib.Builders
             {
                 return 1;
             }
-            else if (SlideSizes.Cy < Globals.px12700)
+            else if (SlideSizes.Cy < Globals.px914400)
             {
-                return Globals.px12700 *1.0 / SlideSizes.Cy;
+                return Globals.px12700 *1.0   / SlideSizes.Cy * Globals.px96;
             }
             else
             {
-                return SlideSizes.Cy *1.0/ Globals.px12700;
+                return SlideSizes.Cy *1.0 * Globals.px96 / Globals.px914400;
             }
         }
 
         public List<PPTSlide> GetPPTSlides(string path) {
 
-            string fileFromPath = Path.GetFileName(path);
-            var inf = new FileInfo(fileFromPath);
-            string fileName = Path.GetFileNameWithoutExtension(inf.Name);
-            string dir = Path.GetDirectoryName(Path.GetDirectoryName(Environment.CurrentDirectory));
-             string destDir = Path.Combine(dir, "F:\\ppt-path");
-            PresentationDocument presentationDocument = null;
+           // string fileFromPath = Path.GetFileName(path);
+           // var inf = new FileInfo(fileFromPath);
+           // string fileName = Path.GetFileNameWithoutExtension(inf.Name);
+           // string dir = Path.GetDirectoryName(Path.GetDirectoryName(Environment.CurrentDirectory));
+          
+            
             try
             {
                 presentationDocument = PresentationDocument.Open(path, false);
@@ -84,8 +85,8 @@ namespace HTEXLib.Builders
          
             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, fileName);
-            presentationDocument.Close();
+            List<PPTSlide> pptSlides = GetPPTSlidesFromParts(slideParts, presentationDocument.PresentationPart.Presentation.DefaultTextStyle, presentationDocument.PresentationPart.SlideMasterParts, presentationDocument);
+          
             //List<PPTImage> pictures = new List<PPTImage>();
             //foreach (PPTSlide slide in pptSlides)
             //    foreach (PPTShapeBase baseShape in slide.ContainerShape.Elements) {
@@ -96,12 +97,12 @@ namespace HTEXLib.Builders
             // var pptInteropt = new PPTBackgroundBuilderInterop(path, pictures);
             //pptInteropt.ExportPresentationImages(destDir);
             //pptInteropt = null;
-            //GC.Collect();
+            //
 
             return pptSlides;
         }
 
-        private List<PPTSlide> GetPPTSlidesFromParts(IEnumerable<SlidePart> slideParts, DefaultTextStyle defaultTextStyle, IEnumerable<SlideMasterPart> slideMasterParts, PresentationDocument presentationDocument, string fileName)
+        private List<PPTSlide> GetPPTSlidesFromParts(IEnumerable<SlidePart> slideParts, DefaultTextStyle defaultTextStyle, IEnumerable<SlideMasterPart> slideMasterParts, PresentationDocument presentationDocument)
         {
             var pptSlides = new List<PPTSlide>();
             int slideIndex = 1;
@@ -135,8 +136,9 @@ namespace HTEXLib.Builders
                 {
                     pptSlides[pptSlides.Count - 1].advanceAfterTime = int.Parse(slidePart.Slide.Transition.AdvanceAfterTime.Value);
                 }
-                var pptSlide = new PPTSlide(slidePart, slideIndex++, defaultTextStyle, fileName, SlideSizes, slideMaster, root,media);
+                var pptSlide = new PPTSlide(slidePart, slideIndex, defaultTextStyle,  SlideSizes, slideMaster, root,media);
                 pptSlides.Add(pptSlide);
+                slideIndex++;
             }
             return pptSlides;
         }

+ 61 - 1
HTEXLib/Builders/PPTContainerShapeBuilder.cs

@@ -11,11 +11,71 @@ namespace HTEXLib.Builders
 {
     internal class PPTContainerShapeBuilder
     {
+        public PPTContainerShape GetPPTContainerShape(SlideLayoutPart slidePart, PPTSlide slide)
+        {
+            var pptContainerShape = new PPTContainerShape();
+            pptContainerShape.Elements = new List<PPTShapeBase>();
+            var objs = slidePart.SlideLayout.Descendants();
+
+            foreach (object obj in objs)
+            {
+
+                if (typeof(DocumentFormat.OpenXml.Presentation.Shape).Equals(obj.GetType()))
+                {
+                    //p:sp
+                    pptContainerShape.Elements.Add(new PPTShape(slidePart, (DocumentFormat.OpenXml.Presentation.Shape)obj, slide));
+                }
+                else if (typeof(Picture).Equals(obj.GetType()))
+                {
+                    //p:pic
+                    pptContainerShape.Elements.Add(new PPTImage(slidePart, (Picture)obj));
+                }
+                else if (typeof(GraphicFrame).Equals(obj.GetType()))
+                {
+                    //p:graphicFrame  Chart, Diagram, Table
+                    pptContainerShape.Elements.Add(new PPTGraphicFrame(slidePart, (GraphicFrame)obj));
+                }
+                else if (typeof(GroupShape).Equals(obj.GetType()))
+                {
+                    //p:grpSp
+                    pptContainerShape.Elements.Add(new PPTGroupShape(slidePart, (GroupShape)obj));
+                }
+                else if (typeof(ConnectionShape).Equals(obj.GetType()))
+                {
+                    //p:cxnSp
+                    pptContainerShape.Elements.Add(new PPTConnectionShape(slidePart, (ConnectionShape)obj));
+                }
+                else if (typeof(AlternateContent).Equals(obj.GetType()))
+                {
+                    ///Equations and formulas as Image  处理公式 方程等
+                    AlternateContent alternateContent = (AlternateContent)obj;
+                    var element = alternateContent.ChildElements.Where(x => typeof(AlternateContentFallback).Equals(x.GetType())).FirstOrDefault();
+                    if (element != null)
+                    {
+                        AlternateContentFallback alternateContentFallback = (AlternateContentFallback)element;
+                        if (typeof(DocumentFormat.OpenXml.Presentation.Shape).Equals(alternateContentFallback.ChildElements.First().GetType()))
+                        {
+                            pptContainerShape.Elements.Add(new PPTShape(slidePart, (DocumentFormat.OpenXml.Presentation.Shape)alternateContentFallback.First(), slide));
+                        }
+                        else if (typeof(Picture).Equals(alternateContentFallback.ChildElements.First().GetType()))
+                        {
+                            pptContainerShape.Elements.Add(new PPTImage(slidePart, (Picture)obj));
+                        }
+                    }
+                    //MathML
+                    // pptContainerShape.Elements.Add(new PPTAlternateContent(slidePart, (AlternateContent)obj, slide));
+                    ///  处理公式 方程等
+                }
+            }
+            return pptContainerShape;
+        }
         public PPTContainerShape GetPPTContainerShape(SlidePart slidePart, PPTSlide slide)
         {
             var pptContainerShape = new PPTContainerShape();
             pptContainerShape.Elements = new List<PPTShapeBase>();
-            foreach (object obj in slidePart.Slide.Descendants())
+            var objs = slidePart.Slide.Descendants();
+
+            foreach (object obj in objs)
             {
                
                 if (typeof(DocumentFormat.OpenXml.Presentation.Shape).Equals(obj.GetType()))

+ 2 - 2
HTEXLib/Controller/HtexController.cs

@@ -31,7 +31,7 @@ namespace HTEXLib.Controller
         /// </summary>
         private dynamic gv { get; set; }
         //  private readonly StringBuilder _htmlPart;
-        private List<HtexElement> htexElements;
+        private List<Item> htexElements;
         private readonly PPTSlide _mSlide;
         private const string JS_DIR_NAME = "temp";
         public double SlideWidth { get; set; }
@@ -43,7 +43,7 @@ namespace HTEXLib.Controller
             _numberOfSlides = 1;
             _allSlidesCount = slidesNumber;
             _slideIndex = slideCounter;
-            this.htexElements = new List<HtexElement>();
+            this.htexElements = new List<Item>();
             
         }
 

+ 163 - 45
HTEXLib/Helpers/ShapeHelpers/PPTXHelper.cs

@@ -9,6 +9,8 @@ using DocumentFormat.OpenXml.Presentation;
 using DocumentFormat.OpenXml.Drawing;
 using HTEXLib.Models;
 using ColorType = DocumentFormat.OpenXml.Drawing.ColorType;
+using System.Linq;
+using DocumentFormat.OpenXml.Packaging;
 
 namespace HTEXLib.Helpers.ShapeHelpers
 {
@@ -19,6 +21,8 @@ namespace HTEXLib.Helpers.ShapeHelpers
         public string EffectColor { get; set; }
         public string FontColor { get; set; }
     }
+ 
+
     public static class PPTXHelper
     {
         // StyleMatrixReferenceType
@@ -50,7 +54,10 @@ namespace HTEXLib.Helpers.ShapeHelpers
         ///  处理 FontReference   字体  a:fontRef
         /// </summary>
         /// <param name="shapeStyle"></param>
-        public static SlideColor DoShapeStyle(DocumentFormat.OpenXml.Presentation.ShapeStyle shapeStyle, PPTSlide slide) {
+        public static SlideColor DoShapeStyle(DocumentFormat.OpenXml.Presentation.ShapeStyle shapeStyle, PPTSlide slide, string type) {
+            if (shapeStyle == null) {
+                return null;
+            }
             string LineColor = StyleMatrixReferenceColors(shapeStyle.LineReference, slide);
             string FillColor = StyleMatrixReferenceColors(shapeStyle.FillReference, slide);
             string EffectColor = StyleMatrixReferenceColors(shapeStyle.EffectReference, slide);
@@ -62,59 +69,70 @@ namespace HTEXLib.Helpers.ShapeHelpers
         /// </summary>
         /// <param name="shapeProperties"></param>
         /// <param name="slide"></param>
-        public static void DoShapeProperties(DocumentFormat.OpenXml.Presentation.ShapeProperties shapeProperties, PPTSlide slide) {
+        public static HTEXLib.Models.HTEX.ShapeStyle DoShapeProperties(DocumentFormat.OpenXml.Presentation.ShapeProperties shapeProperties, PPTSlide slide, string type) {
             //Outline
-            var lnNode = shapeProperties.GetTextByPath("//a:ln");
+            var lnNode = shapeProperties.GetFirstChild<Outline>();
+            Border border = null;
             if (lnNode != null)
             {
-                Border  border  = DoLn(new Outline(lnNode.ToString()),slide);
+                border  = DoLn(lnNode, slide,type);
             }
             Fill fill = new Fill() { type = -1 };
-            var gradFill = shapeProperties.GetTextByPath("a:gradFill");
+            var gradFill = shapeProperties.GetFirstChild<GradientFill>();
             if (gradFill != null)
             {
                 fill.type = 2;
-                fill.gradientFill = DoGradientFill(new GradientFill(gradFill.ToString()), slide);
+                fill.gradientFill = DoGradientFill(gradFill, slide);
             }
-            var noFill = shapeProperties.GetTextByPath("a:noFill");
+            var noFill = shapeProperties.GetFirstChild<NoFill>();
             if (noFill != null)
             {
                 fill.type = 0;
             }
-            var pattFill = shapeProperties.GetTextByPath("a:pattFill");
+            var pattFill = shapeProperties.GetFirstChild<PatternFill>();
             if (pattFill != null)
             {
 
-                DocumentFormat.OpenXml.Drawing.PatternFill patternFill = new PatternFill(pattFill.ToString());
-                HtexPattFill htexPattFill = DoPattFill(patternFill, slide);
+               
+                HtexPattFill htexPattFill = DoPattFill(pattFill, slide);
                 fill.type = 4;
                 fill.pattFill = htexPattFill;
             }
-            var solidFill = shapeProperties.GetTextByPath("a:solidFill");
+            var solidFill = shapeProperties.GetFirstChild<SolidFill>();
             if (solidFill != null)
             {
                 fill.type = 1;
-                fill.solidFill = ReadSolidFillColors(new SolidFill(solidFill.ToString()), slide);
+                fill.solidFill = ReadSolidFillColors(solidFill, slide);
             }
-            var groupFill = shapeProperties.GetTextByPath("a:groupFill");
+            var groupFill = shapeProperties.GetFirstChild<GroupFill>();
             if (groupFill != null)
             {
                 fill.type =5;
               //  fill.solidFill = ReadSolidFillColors(new SolidFill(solidFill.ToString()), slide);
             }
-            var blipFill = shapeProperties.GetTextByPath("a:blipFill");
+            var blipFill = shapeProperties.GetFirstChild<DocumentFormat.OpenXml.Drawing.BlipFill>();
             if (blipFill != null)
             {
                 fill.type = 3;
+                fill.blipFill = DoBlipFill(blipFill, slide);
                 //  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>();
+            return new HTEXLib.Models.HTEX.ShapeStyle {fill=fill,border= border };
         }
-        public static HtexBlipFill DoBlipFill(DocumentFormat.OpenXml.Drawing.BlipFill blipFill, Slide slide) {
+        public static HtexBlipFill DoBlipFill(DocumentFormat.OpenXml.Drawing.BlipFill blipFill, PPTSlide slide) {
             HtexBlipFill htexBlipFill = new HtexBlipFill();
             SourceRectangle source= blipFill.SourceRectangle; ///源矩形  srcRect可能无用
             htexBlipFill.dip = blipFill.Dpi;
-            htexBlipFill.rotWithShape = blipFill.RotateWithShape;
+            if (blipFill.RotateWithShape != null) {
+                htexBlipFill.rotWithShape = blipFill.RotateWithShape;
+            }
+            { htexBlipFill.rotWithShape =true; }
+           
             var fillRect = blipFill.GetTextByPath("a:stretch/a:fillRect");///拉伸
             if (fillRect != null) {
                 htexBlipFill.fillRect = new Vector
@@ -134,7 +152,85 @@ namespace HTEXLib.Helpers.ShapeHelpers
             Tile tile= blipFill.GetFirstChild <Tile>();
             if (tile != null) {
                 ///algn (Alignment) flip (Tile Flipping)  sx (Horizontal Ratio) sy (Vertical Ratio) tx (Horizontal Offset) ty (Vertical Offset)
+                htexBlipFill.tile = new HtexTile { algn=tile.Alignment,flip=tile.Flip,sx=tile.HorizontalRatio,sy=tile.VerticalRatio,tx=tile.HorizontalOffset,ty=tile.VerticalOffset};
+            }
+            var Embed = blipFill.Blip.Embed;
+            var Link = blipFill.Blip.Link;
+            //slide.SlideLayoutPart
+            var part = slide.SlidePart.Parts.Where(x => x.RelationshipId == Embed).FirstOrDefault() ;
+            if (part != null) {
+                var url= part.OpenXmlPart.Uri .ToString().Replace("../","/ppt/");
+                var thumbnail = slide.Media.Where(x => x.Attributes().Select(y => y.Value == url).FirstOrDefault()).FirstOrDefault();
+                if (thumbnail != null)
+                {
+                    var contentType = thumbnail.Attribute("{http://schemas.microsoft.com/office/2006/xmlPackage}contentType").Value;
+                    var data = thumbnail.Value;
+                    url = "data:" + contentType + ";base64," + data;
+                    url = url.Replace("\r\n", "");
+                    htexBlipFill.url = url;
+                    htexBlipFill.urlType = "base64";
+                    htexBlipFill.contentType = contentType;
+
+                }
+            }
+            //TODO 图片元素的更多信息需要后期继续实现,如滤镜,裁剪,图片颜色,图片校正等
+            return htexBlipFill;
+        }
+        public static HtexBlipFill DoBlipFill(DocumentFormat.OpenXml.Presentation.BlipFill blipFill, PPTSlide slide)
+        {
+            HtexBlipFill htexBlipFill = new HtexBlipFill();
+            SourceRectangle source = blipFill.SourceRectangle; ///源矩形  srcRect可能无用
+            htexBlipFill.dip = blipFill.Dpi;
+            if (blipFill.RotateWithShape != null)
+            {
+                htexBlipFill.rotWithShape = blipFill.RotateWithShape;
+            }
+            { htexBlipFill.rotWithShape = true; }
+
+            var fillRect = blipFill.GetTextByPath("a:stretch/a:fillRect");///拉伸
+            if (fillRect != null)
+            {
+                htexBlipFill.fillRect = new Vector
+                {
+                    t = fillRect.Attribute("t") != null ? int.Parse(fillRect.Attribute("t").Value) / 1000 : 0,
+                    l = fillRect.Attribute("l") != null ? int.Parse(fillRect.Attribute("l").Value) / 1000 : 0,
+                    r = fillRect.Attribute("r") != null ? int.Parse(fillRect.Attribute("r").Value) / 1000 : 0,
+                    b = fillRect.Attribute("b") != null ? int.Parse(fillRect.Attribute("b").Value) / 1000 : 0
+                };
+            }
+            var alphaModFix = blipFill.Blip.GetTextByPath("a:alphaModFix");
+            if (alphaModFix != null)
+            {
+                if (alphaModFix.Attribute("amt") != null)
+                {
+                    htexBlipFill.opacity = int.Parse(alphaModFix.Attribute("amt").Value) * 1.0 / 1000;
+                }
+            }
+            Tile tile = blipFill.GetFirstChild<Tile>();
+            if (tile != null)
+            {
+                ///algn (Alignment) flip (Tile Flipping)  sx (Horizontal Ratio) sy (Vertical Ratio) tx (Horizontal Offset) ty (Vertical Offset)
+            }
+            var Embed = blipFill.Blip.Embed;
+            var Link = blipFill.Blip.Link;
+            //slide.SlideLayoutPart
+            var part = slide.SlidePart.Parts.Where(x => x.RelationshipId == Embed).FirstOrDefault();
+            if (part != null)
+            {
+                var url = part.OpenXmlPart.Uri.ToString().Replace("../", "/ppt/");
+                var thumbnail = slide.Media.Where(x => x.Attributes().Select(y => y.Value == url).FirstOrDefault()).FirstOrDefault();
+                if (thumbnail != null)
+                {
+                    var contentType = thumbnail.Attribute("{http://schemas.microsoft.com/office/2006/xmlPackage}contentType").Value;
+                    var data = thumbnail.Value;
+                    url = "data:" + contentType + ";base64," + data;
+                    url = url.Replace("\r\n", "");
+                    htexBlipFill.url = url;
+                    htexBlipFill.urlType = "base64";
+                    htexBlipFill.contentType = contentType;
+                }
             }
+            //TODO 图片元素的更多信息需要后期继续实现,如滤镜,裁剪,图片颜色,图片校正等
             return htexBlipFill;
         }
         /// <summary>
@@ -142,12 +238,19 @@ namespace HTEXLib.Helpers.ShapeHelpers
         /// </summary>
         /// <param name="shapeProperties"></param>
         /// <param name="slide"></param>
-        public static Border DoLn(DocumentFormat.OpenXml.Drawing.Outline outline, PPTSlide slide) {
+        public static Border DoLn(DocumentFormat.OpenXml.Drawing.Outline 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;
-            if (outline.Width != null) {
-                Width=   double.Parse(outline.Width) * 1.0 / Globals.px12700 ;
+            if (outline.Width != null)
+            {
+                Width = double.Parse(outline.Width) * 1.0 * Globals.px96 / Globals.px914400;
+            }
+            else {
+                if (Shapetype == "CxnSp") {
+                    Width = 0.75;
+                }
+                
             }
             // Center = 0,
             // Insert = 1
@@ -179,64 +282,67 @@ namespace HTEXLib.Helpers.ShapeHelpers
                 cap = Convert.ToInt32(outline.CapType);
             }
             border.outline = new HtexOutline { Width = Width, algn = algn, cmpd = cmpd, cap = cap };
-            var gradFill = outline.GetTextByPath("//a:gradFill");
+            var gradFill = outline.GetFirstChild<GradientFill>();
             if (gradFill != null)
             {
                 border.color.type = 2;
-                border.color.gradientFill = DoGradientFill(new GradientFill(gradFill.ToString()), slide);
+                border.color.gradientFill = DoGradientFill(gradFill, slide);
             }
-            var noFill = outline.GetTextByPath("//a:noFill");
+            var noFill = outline.GetFirstChild<NoFill>();
             if (noFill != null)
             {
                 border.color.type = 0;
             }
-            var pattFill = outline.GetTextByPath("//a:pattFill");
+            var pattFill = outline.GetFirstChild<PatternFill>();
             if (pattFill != null)
             {
 
-                DocumentFormat.OpenXml.Drawing.PatternFill patternFill = new PatternFill(pattFill.ToString());
-                HtexPattFill htexPattFill = DoPattFill(patternFill, slide);
+                HtexPattFill htexPattFill = DoPattFill(pattFill, slide);
                 border.color.type = 4;
                 border.color.pattFill = htexPattFill;
             }
-            var solidFill = outline.GetTextByPath("//a:solidFill");
+            var solidFill = outline.GetFirstChild<SolidFill>();
             if (solidFill != null)
             {
                 border.color.type = 1;
-                border.color.solidFill = ReadSolidFillColors(new SolidFill(solidFill.ToString()), slide);
+                border.color.solidFill = ReadSolidFillColors(solidFill, slide);
+            }
+            if (Width!=null && Width > 0) {
+                border.type = "solid";
+                border.stroke = "0";
             }
-            var prstDash= outline.GetTextByPath("//a:prstDash"); //预设连接符
+            var prstDash= outline.GetFirstChild<PresetDash>(); //预设连接符
             if (prstDash != null) {
                // PresetDash
                 var  (type, stroke)   = DoPrstDash(prstDash);
                 border.type = type;
                 border.stroke = stroke;
             }
-            if (outline.GetTextByPath("//a:bevel") != null) {
+            if (outline.GetFirstChild<Bevel>() != null) {
                 // 棱台切角
                 border.corner = "bevel";
             }
-            if (outline.GetTextByPath("//a:round")!=null) {
+            if (outline.GetFirstChild<Round>()!=null) {
                 //圆角
                 border.corner = "round";
             }
-            if (outline.GetTextByPath("//a:miter") != null) {
+            if (outline.GetFirstChild<Miter>() != null) {
                 //斜角
                 border.corner = "miter";
             }
-            var headEndNodeAttrs = outline.GetTextByPath("//a:headEnd"); //连接符开始符号
+            var headEndNodeAttrs = outline.GetFirstChild<HeadEnd>(); //连接符开始符号
             if (headEndNodeAttrs != null)
             {
-                border.headEnd = headEndNodeAttrs != null ? headEndNodeAttrs.Attribute("type").Value : null;
+                border.headEnd = headEndNodeAttrs.Type;
             }
-            var tailEndNodeAttrs = outline.GetTextByPath("//a:tailEnd");//末端连接符
-            if (headEndNodeAttrs != null)
+            var tailEndNodeAttrs = outline.GetFirstChild<TailEnd>();//末端连接符
+            if (tailEndNodeAttrs != null)
             {
-                border.tailEnd = tailEndNodeAttrs != null ? tailEndNodeAttrs.Attribute("type").Value : null;
+                border.tailEnd = tailEndNodeAttrs.Type;
             } 
             //TODO
             //outline.GetTextByPath("//a:extLst"); 
-            XElement custDash = outline.GetTextByPath("//a:custDash");//自定义连接线
+            var custDash = outline.GetFirstChild<CustomDash>();//自定义连接线
             if (custDash != null) {
                 var(type, stroke)  = DoCustDash(custDash);
                 border.type = type;
@@ -249,7 +355,7 @@ namespace HTEXLib.Helpers.ShapeHelpers
         /// </summary>
         /// <param name="custDash"></param>
         /// <returns></returns>
-        public static (string type, string stroke) DoCustDash(XElement custDash) {
+        public static (string type, string stroke) DoCustDash(CustomDash custDash) {
             string type = "cust";
             string stroke = "";
             IEnumerable<XElement> elements= custDash.GetTextByPathList("ds");
@@ -278,13 +384,13 @@ namespace HTEXLib.Helpers.ShapeHelpers
         /// </summary>
         /// <param name="presetDash"></param>
         /// <returns></returns>
-        public static (string type, string stroke) DoPrstDash(XElement presetDash)
+        public static (string type, string stroke) DoPrstDash(PresetDash presetDash)
         {
             Border border = new Border();
             string type = "solid";
             string stroke = "0";
             //PresetLineDashValues  枚举
-            string val = presetDash.Attribute("val").Value;
+            string val = presetDash.Val;
             switch (val)
             {
                 case "solid":
@@ -371,17 +477,24 @@ namespace HTEXLib.Helpers.ShapeHelpers
             ///HorizontalAndVertical 	 水平和垂直。
             ///Vertical 垂直
             ///None  无
-            string name =  Enum.GetName(typeof(TileFlipValues), GradientFill.Flip);
+            string name = "None";
+            if (GradientFill.Flip != null) {
+                name = GradientFill.Flip.Value.ToString();
+            }
             gradientFill.flip = name;
             List<ColorPosition> colors = new List<ColorPosition>();
-            bool RotateWithShape = GradientFill.RotateWithShape;
+            bool RotateWithShape = true;
+            if (GradientFill.RotateWithShape != null)
+            {
+                RotateWithShape = GradientFill.RotateWithShape;
+            }
             gradientFill.RotateWithShape = RotateWithShape;
             foreach (GradientStop gradientStop in GradientFill.GradientStopList)
             {
                 colors.Add(new ColorPosition
                 {
                     Color = ColorTypeColors(gradientStop, slide),
-                    Position = gradientStop.Position/// 位置,色带的位置 百分比0-100
+                    Position = gradientStop.Position *1.0/ 1000 /// 位置,色带的位置 百分比0-100
                 });
             }
             gradientFill.colors = colors;
@@ -712,6 +825,9 @@ namespace HTEXLib.Helpers.ShapeHelpers
         }
         public static string ReadThemeSchemeColor(SchemeColor schemeColor, PPTSlide slide)
         {
+            var light1Color1= slide.SlideLayoutPart.SlideMasterPart.
+                      ThemePart;
+        
             string FontColor = "";
             if (schemeColor.Val == "bg1")
             {
@@ -783,7 +899,9 @@ namespace HTEXLib.Helpers.ShapeHelpers
                     FontColor = "#" + folHyperLink.RgbColorModelHex.Val.Value;
                 }
             }
-           FontColor=  ReadAccentSchemeColors(schemeColor,slide);
+            if (string.IsNullOrEmpty(FontColor)) {
+                FontColor = ReadAccentSchemeColors(schemeColor, slide);
+            }
             return FontColor;
         }
 

Diff do ficheiro suprimidas por serem muito extensas
+ 631 - 532
HTEXLib/Helpers/ShapeHelpers/PPTXSvg.cs


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

@@ -176,220 +176,7 @@ namespace HTEXLib
             return colorHex;
         }
 
-        public static Border GetBorder(XmlNode node, bool isSvgMode, string bType, Dictionary<string, string> slideLayoutClrOvride, XmlNode slideMasterContent, XmlNode themeContent)
-        {
-            var borderWidth = 0.0;
-            if (node.Name.Equals("p:cxnSp"))
-            {
-                borderWidth = 0.75;
-            }
-            Border border = new Border() { width = borderWidth };
-
-            XmlNode lineNode = null;
-            if (bType == "shape")
-            {
-                // cssText = "border: ";
-                lineNode = node.GetTextByPath("p:spPr/a:ln");// node["p:spPr"]["a:ln"];
-            }
-            else if (bType == "text")
-            {
-                //  cssText = "";
-                lineNode = ShapeHelper.GetTextByPath(node, "a:rPr/a:ln");// node["a:rPr"]["a:ln"];
-
-            }
-            if (lineNode != null)
-            {
-                XmlNode wnode = lineNode.GetTextByPath("@w");
-                if (wnode != null)
-                {
-                    border.width = double.Parse(wnode.Value) / px12700;
-                }
-                // Border width: 1pt = 12700, default = 0.75pt
-                //  borderWidth = double.Parse(ShapeHelper.GetTextByPath(lineNode, "@w").Value) / px12700;
-                //if (wnode != null || borderWidth < 1)
-                //{
-                //    cssText += "0pt ";
-                //}
-                //else
-                //{
-                //    borderWidth=
-                //    cssText += borderWidth + "pt ";
-                //}
-            }
-
-            // Border type
-            if (lineNode != null)
-            {
-                var borderType = ShapeHelper.GetTextByPath(lineNode, "a:prstDash/@val");
-                if (borderType != null)
-                {
-                    switch (borderType.Value)
-                    {
-                        case "solid":
-                            border.type = "solid";
-                            border.stroke = "0";
-                            break;
-                        case "dash":
-                            border.type += "dashed";
-                            border.stroke = "5";
-                            break;
-                        case "dashDot":
-                            border.type = "dashed";
-                            border.stroke = "5, 5, 1, 5";
-                            break;
-                        case "dot":
-                            border.type = "dotted";
-                            border.stroke = "1, 5";
-                            break;
-                        case "lgDash":
-                            border.type = "dashed";
-                            border.stroke = "10, 5";
-                            break;
-                        case "lgDashDotDot":
-                            border.type = "dashed";
-                            border.stroke = "10, 5, 1, 5, 1, 5";
-                            break;
-                        case "sysDash":
-                            border.type = "dashed";
-                            border.stroke = "5, 2";
-                            break;
-                        case "sysDashDot":
-                            border.type = "dashed";
-                            border.stroke = "5, 2, 1, 5";
-                            break;
-                        case "sysDashDotDot":
-                            border.type = "dashed";
-                            border.stroke = "5, 2, 1, 5, 1, 5";
-                            break;
-                        case "sysDot":
-                            border.type = "dotted";
-                            border.stroke = "2, 5";
-                            break;
-                        case null:
-                        //console.log(borderType);
-                        default:
-                            border.type = "solid";
-                            border.stroke = "0";
-                            break;
-                    }
-                }
-            }
-            else
-            {
-                border.type = "solid";
-                border.stroke = "0";
-            }
-            // Border color
-            string borderColorstr = "";
-            if (lineNode != null)
-            {
-                //var borderColor = ShapeHelper.GetTextByPath(lineNode, "a:solidFill/a:srgbClr/@val");
-                //if (borderColor == null)
-                //{
-                //    var schemeClrNode = ShapeHelper.GetTextByPathList(lineNode, "a:solidFill/a:schemeClr");
-                //    if (schemeClrNode != null)
-                //    {
-                //        var schemeClr = ShapeHelper.GetTextByPath(lineNode, "a:solidFill/a:schemeClr/@val");
-                //        borderColorstr = GetSchemeColorFromTheme(schemeClr.Value, null, slideLayoutClrOvride, themeContent);
-                //        borderColorstr = ShapeHelper.ColorToning(lineNode.OuterXml, borderColorstr);
-                //    }
-                //}
-
-                borderColorstr = GetSolidFill(lineNode, slideLayoutClrOvride, slideMasterContent, themeContent);
-                borderColorstr = ShapeHelper.ColorToning(lineNode.OuterXml, borderColorstr);
-            }
-
-
-            // 2. drawingML namespace
-            if (string.IsNullOrEmpty(borderColorstr))
-            {
-                XmlNode lnRefNode = ShapeHelper.GetTextByPath(node, "p:style/a:lnRef");
-                if (lnRefNode != null)
-                {
-                    borderColorstr = GetSolidFill(lnRefNode, slideLayoutClrOvride, slideMasterContent, themeContent);
-                    borderColorstr = ShapeHelper.ColorToning(lnRefNode.OuterXml, borderColorstr);
-                }
-                //var schemeClrNode = ShapeHelper.GetTextByPathList(node, "p:style/a:lnRef/a:schemeClr");
-                //if (schemeClrNode != null)
-                //{
-                //    var schemeClr = ShapeHelper.GetTextByPath(node, "p:style/a:lnRef/a:schemeClr/@val");
-                //    if (schemeClr != null)
-                //    {
-                //        borderColorstr = GetSchemeColorFromTheme(schemeClr.Value, null, slideLayoutClrOvride, themeContent);
-                //    }
-                //}
-                //if (borderColor != null)
-                //{
-                //    var shade = ShapeHelper.GetTextByPath(node, "p:style/a:lnRef/a:schemeClr/a:shade/@val");
-                //    if (shade != null)
-                //    {
-                //        double shaded = double.Parse(shade.Value) / 100000.0;
-                //        var color = ColorTranslator.FromHtml("#" + borderColor);
-                //        ColorHSL colorHSL = ColorHelper.RgbToHsl(new ColorRGB(color.R, color.G, color.B));
-                //        colorHSL.L = colorHSL.L * shaded;
-                //        ColorRGB colorRGB = colorHSL.HslToRgb();
-                //        borderColorstr = ColorTranslator.ToHtml(Color.FromArgb(colorRGB.R, colorRGB.G, colorRGB.B));
-                //        // borderColor = color.hex.replace("#", "");
-                //    }
-                //}
-
-            }
-            if (!string.IsNullOrEmpty(borderColorstr))
-            {
-                border.color = borderColorstr;
-                if (border.width == 0.0)
-                {
-                    border.width = 1;
-                }
-            }
-            return border;
-
-            //if (borderColor == null)
-            //{
-            //    if (isSvgMode)
-            //    {
-            //        borderColorstr = "none";
-            //    }
-            //    else
-            //    {
-            //        borderColorstr = "#000";
-            //    }
-            //}
-            //else
-            //{
-            //    borderColorstr = "#" + borderColorstr;
-
-            //}
-            //cssText += " " + borderColor + " ";
-            //if (borderType != null)
-            //{
-            //    if (isSvgMode)
-            //    {
-            //        return new Border { Color = borderColorstr, Width = (int)borderWidth, Type = borderType.Value, Stroke = strokeDasharray };
-            //    }
-            //    else
-            //    {
-            //        return border;
-            //    }
-            //}
-            //else
-            //{
-
-            //    if (isSvgMode)
-            //    {
-            //        return new Border { Color = borderColorstr, Width = (int)borderWidth, Type = "", Stroke = strokeDasharray };
-            //    }
-            //    else
-            //    {
-            //        return border;
-            //    }
-            //}
-
-
-
-
-        }
-
+         
         public static string GetSchemeColorFromTheme(string schemeClr, XmlNode sldMasterNode, Dictionary<string, string> slideLayoutClrOvride, XmlNode themeContent)
         {
             //<p:clrMap ...> in slide master

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 11119
HTEXLib/Helpers/ShapeHelpers/ShapeSvg.cs


+ 29 - 2
HTEXLib/Models/Border.cs

@@ -15,9 +15,9 @@ namespace HTEXLib
         /// </summary>
         public string stroke{ get; set; }
         public string dir { get; set; }
-        public HtexOutline outline { get; set; }
+        public HtexOutline outline { get; set; } = new HtexOutline();
 
-        public  Fill color { get; set; }
+        public Fill color { get; set; } = new Fill();
         /// <summary>
         /// 切角  bevel 棱台   round  圆角   斜角 miter
         /// </summary>
@@ -26,4 +26,31 @@ namespace HTEXLib
         public string tailEnd { get; set; }
 
     }
+    public class HtexOutline
+    {
+        public double? Width { get; set; }
+        /// <summary>
+        ///  Center = 0,
+        ///Insert = 1
+        ///20.1.10.39
+        /// </summary>
+        public int? algn { get; set; }
+        /// <summary>
+        ///  20.1.10.15
+        ///Single = 0,
+        ///       Double = 1,
+        ///     ThickThin = 2,
+        ///       ThinThick = 3,
+        ///        Triple = 4
+        /// </summary>
+        public int? cmpd { get; set; }
+        /// <summary>
+        /// 20.1.10.31
+        /// Round = 0,
+        /// Square = 1,
+        ///  Flat = 2
+        /// </summary>
+        public int? cap { get; set; }
+    }
+
 }

+ 10 - 31
HTEXLib/Models/Fill.cs

@@ -21,47 +21,26 @@ namespace HTEXLib
         public HtexBlipFill blipFill { get; set; }
         public HtexGradientFill gradientFill { get; set; }
         public HtexPattFill pattFill { get; set; }
-        public HtexOutline outline { get; set; }
+        //public HtexOutline outline { get; set; }
 
-        public Border border { get; set; }
+        //public Border border { get; set; }
 
     }
     /// <summary>
     ///  3.图片或纹理填充 
     /// </summary>
-    public class HtexOutline
-    {
-        public double? Width { get; set; }
-        /// <summary>
-        ///  Center = 0,
-        ///Insert = 1
-        ///20.1.10.39
-        /// </summary>
-        public int? algn { get; set; }
-        /// <summary>
-        ///  20.1.10.15
-        ///Single = 0,
-        ///       Double = 1,
-        ///     ThickThin = 2,
-        ///       ThinThick = 3,
-        ///        Triple = 4
-        /// </summary>
-        public int? cmpd { get; set; }
-        /// <summary>
-        /// 20.1.10.31
-        /// Round = 0,
-        /// Square = 1,
-        ///  Flat = 2
-        /// </summary>
-        public int? cap { get; set; }
-    }
-
+    
     /// <summary>
     ///  3.图片或纹理填充 
     /// </summary>
     public class HtexBlipFill {
         public Vector fillRect { get; set; }
-        public string image { get; set; }
+        public string url { get; set; }
+        /// <summary>
+        /// base64,link
+        /// </summary>
+        public string urlType { get; set; }
+        public string contentType { get; set; }
         public string dip { get; set; }
         public bool rotWithShape { get; set; } = true;
         public double opacity { get; set; } = 0;
@@ -116,7 +95,7 @@ namespace HTEXLib
     public class ColorPosition
     {
         public string Color { get; set; }
-        public string Position { get; set; }
+        public double Position { get; set; }
     }
     /// <summary>
     /// 偏移向量

+ 17 - 17
HTEXLib/Models/HTEX/HtexConnectionShape.cs

@@ -1,3 +1,4 @@
+using DocumentFormat.OpenXml.Drawing;
 using HTEXLib.Helpers.ShapeHelpers;
 using System;
 using System.Collections.Generic;
@@ -24,7 +25,7 @@ namespace HTEXLib.Models.HTEX
             base.index = index;
             base.type = "CxnSp";
         }
-        public override List<HtexElement> DrawElement()
+        public override List<Item> DrawElement()
         {
             //var xfrm =  connectionShape.element.GetTextByPath("//p:spPr/a:xfrm");
             //var flipV = xfrm.Attribute("flipV");
@@ -40,10 +41,6 @@ namespace HTEXLib.Models.HTEX
             position.flipV = connectionShape.element.ShapeProperties.Transform2D.VerticalFlip!=null && connectionShape.element.ShapeProperties.Transform2D.VerticalFlip.Value?1:0;
             position.flipH = connectionShape.element.ShapeProperties.Transform2D.HorizontalFlip!=null && connectionShape.element.ShapeProperties.Transform2D.HorizontalFlip.Value ? 1 : 0;
              
-            var grndFillFlg = false;
-            var imgFillFlg = false;
-            var headEndNodeAttrs = connectionShape.element.GetTextByPath("//p:spPr/a:ln/a:headEnd");
-            var tailEndNodeAttrs = connectionShape.element.GetTextByPath("//p:spPr/a:ln/a:tailEnd");
             /*
              <xsd:enumeration value="none"/> 无
              <xsd:enumeration value="triangle"/> 三角形-▶
@@ -52,20 +49,23 @@ namespace HTEXLib.Models.HTEX
              <xsd:enumeration value="oval"/> 圆点●
              <xsd:enumeration value="arrow"/>   ->⇱
              */
-            var shapeTypeNode = connectionShape.element.GetTextByPath("p:spPr/a:prstGeom");
-            var shapeType= shapeTypeNode.Attribute("prst").Value;
-            var shapeBorder = PPTXHelper.GetBorder(connectionShape.element, "shape");
+            var shapeTypeNode = connectionShape.element.ShapeProperties.GetFirstChild<PresetGeometry>();
+            var shapeType= shapeTypeNode.Preset.InnerText;
+            var otl = connectionShape.element.ShapeProperties.GetFirstChild<Outline>();
+            var shapeBorder = PPTXHelper.DoLn(otl, slide,type);
             //从ShapeProperties 获取 p:spPr
-            var porp = connectionShape.element.ShapeProperties;
-
-
             //再从 ShapeStyle 获取 p:spPr
-            var colors =  PPTXHelper.DoShapeStyle(connectionShape.element.ShapeStyle, slide);
-           
-            shapeBorder.color = colors.FillColor;
-            Svg svg = PPTXSvg.GenShapeSvg(connectionShape.element, index, shapeType, position.flipV, position, grndFillFlg, imgFillFlg, null, shapeBorder, headEndNodeAttrs, tailEndNodeAttrs);
-            new Connector { position = position, invisible = invisible, animatable = animatable, index = index, id = id, svg = svg, border = shapeBorder };
-            return null; 
+            if (shapeBorder.color == null|| shapeBorder.color.type==-1) {
+                SlideColor slideColor = PPTXHelper.DoShapeStyle(connectionShape.element.ShapeStyle, slide,type);
+                if (slideColor != null) {
+                    shapeBorder.color.solidFill = slideColor.LineColor;
+                    shapeBorder.color.type = 2;
+                }
+            }
+            Svg svg = PPTXSvg.GenShapeSvg(connectionShape.element, index, shapeType, position,   shapeBorder);
+          //  position = position ,mediaType = "image",type = type,index = index,animatable = animatable ,invisible = invisible
+            Item item= new Connector { position = position,type=type,cxnType=shapeType, invisible = invisible, animatable = animatable, index = index, id = id, svg = svg, border = shapeBorder };
+            return new List<Item>() { item }; 
         }
     }
 }

+ 1 - 1
HTEXLib/Models/HTEX/HtexElement.cs

@@ -26,6 +26,6 @@ namespace HTEXLib.Models.HTEX
         public int flipH { get; set; } = 0;
         //垂直翻转
         public int flipV { get; set; } = 0;
-        public abstract List<HtexElement> DrawElement();
+        public abstract List<Item> DrawElement();
     }
 }

+ 1 - 1
HTEXLib/Models/HTEX/HtexGroupShape.cs

@@ -24,7 +24,7 @@ namespace HTEXLib.Models.HTEX
             base.type = "Group";
         }
         public Inner.PPTGroupShape groupShape { get; set; }
-        public override List<HtexElement> DrawElement()
+        public override List<Item> DrawElement()
         {
             throw new NotImplementedException();
         }

+ 80 - 3
HTEXLib/Models/HTEX/HtexImage.cs

@@ -1,5 +1,8 @@
+using DocumentFormat.OpenXml.Drawing;
+using HTEXLib.Helpers.ShapeHelpers;
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Text;
 
 namespace HTEXLib.Models.HTEX
@@ -27,9 +30,83 @@ namespace HTEXLib.Models.HTEX
             base.type = "Media";
         }
         public Inner.PPTImage image { get; set; }
-        public override List<HtexElement> DrawElement()
-        {
-            throw new NotImplementedException();
+        public override List<Item> DrawElement()
+        { 
+            Position position = new Position { cx = width, cy = height, x = left, y = top, rot = rot };
+            var ShapeStyle = PPTXHelper.DoShapeProperties(image.element.ShapeProperties, slide,type);
+            Media media = new Media() { position = position ,mediaType= "image",type=type,index=index,animatable=animatable ,invisible=invisible};
+            /*
+             *  cNvPicPr (非可视图片绘图属性)	§19.3.1.11
+                cNvPr (非可视绘图属性)	§19.3.1.12
+                nvPr (非可视属性)	§19.3.1.33
+             */
+            var WaveAudioFile = image.element.NonVisualPictureProperties.ApplicationNonVisualDrawingProperties.GetFirstChild<WaveAudioFile>();
+            var AudioFromFile = image.element.NonVisualPictureProperties.ApplicationNonVisualDrawingProperties.GetFirstChild<AudioFromFile>();
+            var VideoFromFile = image.element.NonVisualPictureProperties.ApplicationNonVisualDrawingProperties.GetFirstChild<VideoFromFile>();
+            if (WaveAudioFile != null) { 
+            
+            }
+            if (AudioFromFile != null) {
+                string url = AudioFromFile.Link;
+                var part = slide.SlidePart.DataPartReferenceRelationships.Where(x => x.Id == url).FirstOrDefault();
+                if (part != null) {
+                    url = part.Uri.ToString().Replace("../", "/ppt/");
+                    HtexBlipFill file = new HtexBlipFill { url = url, urlType = "link" };
+                    var thumbnail = slide.Media.Where(x => x.Attributes().Select(y => y.Value == url).FirstOrDefault()).FirstOrDefault();
+                    if (thumbnail != null) {
+                        var contentType = thumbnail.Attribute("{http://schemas.microsoft.com/office/2006/xmlPackage}contentType").Value;
+                        file.contentType = contentType;
+                    }
+                    media.file = file;
+                }
+            }
+            if (VideoFromFile != null) {
+                string url = VideoFromFile.Link;
+                var part = slide.SlidePart.DataPartReferenceRelationships.Where(x => x.Id == url).FirstOrDefault();
+                if (part != null)
+                {
+                    url = part.Uri.ToString().Replace("../", "/ppt/");
+                    HtexBlipFill file = new HtexBlipFill { url = url, urlType = "link" };
+                    var thumbnail = slide.Media.Where(x => x.Attributes().Select(y => y.Value == url).FirstOrDefault()).FirstOrDefault();
+                    if (thumbnail != null)
+                    {
+                        var contentType = thumbnail.Attribute("{http://schemas.microsoft.com/office/2006/xmlPackage}contentType").Value;
+                        file.contentType = contentType;
+                    }
+                    media.file = file;
+                }
+            }
+            SlideColor slideColor = PPTXHelper.DoShapeStyle(image.element.ShapeStyle, slide,type);
+            //从ShapeProperties 获取 p:spPr
+            //再从 ShapeStyle 获取 p:spPr
+            if (ShapeStyle.border == null || ShapeStyle.border.color == null || ShapeStyle.border.color.type == -1)
+            {
+                if (slideColor != null)
+                {
+                    media.border.color.solidFill = slideColor.LineColor;
+                    media.border.color.type = 2;
+                }
+            }
+            else
+            {
+                media.border = ShapeStyle.border;
+            }
+            if (ShapeStyle.fill == null || ShapeStyle.fill.type == -1)
+            {
+                if (slideColor != null)
+                {
+                    media.fill.solidFill = slideColor.FillColor;
+                    media.fill.type = 2;
+                }
+            }
+            else
+            {
+                media.fill = ShapeStyle.fill;
+            }
+            HtexBlipFill htexBlipFill = PPTXHelper.DoBlipFill(image.element.BlipFill, slide);
+            media.image = htexBlipFill;
+
+            return new List<Item>() { media }; 
         }
     }
 }

+ 1 - 1
HTEXLib/Models/HTEX/HtexImageGIF.cs

@@ -6,7 +6,7 @@ namespace HTEXLib.Models.HTEX
 {
     public class HtexImageGIF : HtexElement
     {
-        public override List<HtexElement> DrawElement()
+        public override List<Item> DrawElement()
         {
             throw new NotImplementedException();
         }

+ 362 - 4
HTEXLib/Models/HTEX/HtexShape.cs

@@ -1,6 +1,9 @@
+using DocumentFormat.OpenXml.Drawing;
+using HTEXLib.Helpers.ShapeHelpers;
 using HTEXLib.Models.Inner;
 using System;
 using System.Collections.Generic;
+using System.Drawing;
 using System.Text;
 
 namespace HTEXLib.Models.HTEX
@@ -8,7 +11,7 @@ namespace HTEXLib.Models.HTEX
     public class HtexShape : HtexElement
     {
         public PPTShape Shape { get; set; }
-        public double Rotate { get; set; }
+      //  public double Rotate { get; set; }
         public string HyperLink { get; set; }
         private int slideIndex;
 
@@ -31,12 +34,367 @@ namespace HTEXLib.Models.HTEX
             base.type = "Sp";
         }
       
-        public override List<HtexElement> DrawElement()
+        public override List<Item> DrawElement()
         {
 
-            string style = invisible ? "DC0" : "DC1";
+           // string style = invisible ? "DC0" : "DC1";
 
-            return null; 
+            Position position = new Position { cx= width, cy= height, x=left,y=top,rot=rot};
+            var ShapeStyle =PPTXHelper.DoShapeProperties(Shape.element.ShapeProperties, slide,type);
+            //position = position ,mediaType = "image",type = type,index = index,animatable = animatable ,invisible = invisible
+            Shape shape = new Shape() { paragraph = DrawText(),position=position ,type=type,index=index,animatable=animatable,invisible=invisible };
+            var shapeTypeNode = Shape.element.ShapeProperties.GetFirstChild<PresetGeometry>();
+            var shapeType = shapeTypeNode.Preset.InnerText;
+            SlideColor slideColor = PPTXHelper.DoShapeStyle(Shape.element.ShapeStyle, slide,type);
+            //从ShapeProperties 获取 p:spPr
+            //再从 ShapeStyle 获取 p:spPr
+            if (ShapeStyle.border == null || ShapeStyle.border.color == null || ShapeStyle.border.color.type == -1)
+            {
+                if (slideColor != null)
+                {
+                    shape.border.color.solidFill = slideColor.LineColor;
+                    shape.border.color.type = 2;
+                }
+            }
+            else {
+                shape.border = ShapeStyle.border;
+            }
+            if (ShapeStyle.fill == null || ShapeStyle.fill.type == -1)
+            {
+                if (slideColor != null)
+                {
+                    shape.fill.solidFill = slideColor.FillColor;
+                    shape.fill.type = 2;
+                }
+            }
+            else {
+                shape.fill = ShapeStyle.fill;
+            }
+            Svg svg = PPTXSvg.GenShapeSvg(Shape.element, index, shapeType, position,  shape.border);
+            shape.svg = svg;
+            shape.shapeType = shapeType;
+            var elmt = new List<Item> ();
+            elmt.Add(shape);
+            return elmt;
+        }
+
+        public List<Paragraph> DrawText() {
+            double top = getTopForCurrentAnchoring(this.Shape.VerticalAlign, this.Shape.Texts);
+            List<Paragraph> Paragraphs = new List<Paragraph>();
+            foreach (var par in Shape.Texts)
+            {
+                double paragraphTop = this.top + (this.Shape.VerticalAlign.Equals(DocumentFormat.OpenXml.Drawing.TextAnchoringTypeValues.Top) ? par.getSpaceBeforePoints() : 0);
+                Paragraph paragraph= new HTEXLib.Paragraph { animatable = par.Animatable ,invisible=par.Invisible};
+                paragraph.style.position.y = paragraphTop;
+                paragraph.style.position.x =this.left;
+                paragraph.style.position.cx = width;
+                paragraph.style.position.cy = height;
+                paragraph.style.position.rot = rot;
+
+                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;
+                    Font font = new System.Drawing.Font(par.defaultRunProperties.FontFamily.ToString(), points);
+                    newTop = font.Height;
+                }
+                List<HtexText> processedElements = new List<HtexText>();
+                foreach (var text in breakTextsToShape(par)) {
+                    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);
+                    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);
+                    //Text must already be broken to lines
+                    //Size size = MeasureString(currentString, font);
+                    //                     if (size.Width > this.width - par.Indent - par.marginLeft - par.marginRight) 
+                    //                     {
+                    //                         top += newTop;
+                    //                         left = 0;
+                    //                         fixLeftSpacingForAlignment(processedElements, par, font);
+                    //                         processedElements.Clear();
+                    //                     }
+                    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: 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 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 - Shape.LeftInset - Shape.RightInset) - combinedWidth) / 2;
+            else if ("Right".Equals(par.Align))
+                currentLeft = (this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight - Shape.LeftInset - Shape.RightInset) - combinedWidth;
+
+            foreach (HtexText textElement in textElements)
+            {
+                textElement.setLeft(currentLeft + par.Indent + bulletOffset + par.marginLeft + Shape.LeftInset);
+                currentLeft += textElement.width;
+            }
+        }
+
+        //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, 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 - Shape.LeftInset - Shape.RightInset) - combinedWidth) / 2;
+            else if ("Right".Equals(par.Align))
+                firstLeft = (this.width - par.Indent - bulletOffset - par.marginLeft - par.marginRight - Shape.LeftInset - Shape.RightInset) - 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 + Shape.LeftInset + MeasureString(combinedText.ToString(), font));
+                if (textElement.PictureBullet)
+                    combinedWidth += textElement.bulletSize;
+                else
+                    combinedText.Append(textElement.Text);
+            }
+        }
+
+        private double getTopForCurrentAnchoring(DocumentFormat.OpenXml.Drawing.TextAnchoringTypeValues anchoring, LinkedList<PPTParagraph> paragraphList)
+        {
+            if (anchoring.Equals(DocumentFormat.OpenXml.Drawing.TextAnchoringTypeValues.Top))
+                return Shape.TopInset;
+
+            double combinedHeight = 0;
+            foreach (PPTParagraph par in paragraphList)
+            {
+                int newTop = 0;
+                IEnumerable<PPTRunProperties> splitText = breakTextsToShape(par);
+                foreach (var text in splitText)
+                {
+                    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);
+                    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);
+                    if (text.isBreak)
+                    {
+                        combinedHeight += newTop;
+                        newTop = font.Height;
+                        continue;
+                    }
+
+                    newTop = font.Height > newTop ? font.Height : newTop;
+
+                }
+                combinedHeight += par.getLineSpacingInPointsFromFont(newTop);
+                combinedHeight += par.getSpaceBeforePoints(newTop);
+                combinedHeight += par.getSpaceAfterPoints(newTop);
+            }
+
+            combinedHeight += Shape.TopInset + Shape.BottomInset;
+            if (anchoring.Equals(DocumentFormat.OpenXml.Drawing.TextAnchoringTypeValues.Bottom))
+                return this.height - combinedHeight;
+
+            return (this.height - combinedHeight) / 2;  //Center align
+
+
+
+        }
+
+        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;
+                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, 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();
         }
     }
 }

+ 7 - 11
HTEXLib/Models/HTEX/HtexSlide.cs

@@ -16,21 +16,20 @@ namespace HTEXLib.Models.HTEX
             base.cssClass = slideClass;
             this.slideIndex = slideIndex;
         }
-        public override List<HtexElement> DrawElement()
+        public override List<Item> DrawElement()
         {
-            List<HtexElement>  htexElements = new List<HtexElement>();
+            List<Item>  htexElements = new List<Item>();
             
             htexElements.AddRange(GenerateElements());
-            
             return htexElements;
         }
 
-        private List<HtexElement> GenerateElements()
+        private List<Item> GenerateElements()
         {
-            List<HtexElement> htexElements = null;
+            List<Item> htexElements = null;
             if (ContainerShape.Elements.Count > 0)
             {
-                htexElements = new List<HtexElement>();
+                htexElements = new List<Item>();
                 int index = 0;
                 foreach (PPTShapeBase baseShape in ContainerShape.Elements)
                 {
@@ -45,7 +44,7 @@ namespace HTEXLib.Models.HTEX
             }
             return htexElements;
         }
-        private List<HtexElement> DrawShapeHtex( PPTShapeBase baseShape,int index)
+        private List<Item> DrawShapeHtex( PPTShapeBase baseShape,int index)
         {
             double left = baseShape.VisualShapeProp.Left();
             double width = baseShape.VisualShapeProp.PixelWidth();
@@ -85,7 +84,7 @@ namespace HTEXLib.Models.HTEX
                                                         left, invisible, animatable, slideIndex,index, shape, slide)
                 {
                     Shape = shape,
-                    Rotate = baseShape.VisualShapeProp.Rotate,
+                    //rot = baseShape.VisualShapeProp.Rotate,
                     HyperLink = clickLinkUrl
                 };
                 
@@ -105,14 +104,11 @@ namespace HTEXLib.Models.HTEX
                 {
                     HyperLink = clickLinkUrl
                 };
-
                 return htmlImage.DrawElement();
             }
             else {
                 return null;
             }
-              
-
         }
 
 

+ 1 - 1
HTEXLib/Models/HTEX/HtexSmartArt.cs

@@ -26,7 +26,7 @@ namespace HTEXLib.Models.HTEX
         }
         public Inner.PPTGraphicFrame graphicFrame { get; set; }
 
-        public override List<HtexElement> DrawElement()
+        public override List<Item> DrawElement()
         {
             throw new NotImplementedException();
         }

+ 34 - 6
HTEXLib/Models/HTEX/HtexText.cs

@@ -1,3 +1,4 @@
+using HTEXLib.Models.Inner;
 using System;
 using System.Collections.Generic;
 using System.Text;
@@ -6,7 +7,7 @@ namespace HTEXLib.Models.HTEX
 {
     public class HtexText : HtexElement
     {
-      
+        public string id { get; set; }
         public string Text { get; set; }
         public bool PictureBullet { get; set; }
         public bool isBullet { get; set; }
@@ -16,9 +17,9 @@ namespace HTEXLib.Models.HTEX
         private bool italic;
         private string underline;
         public int slideIndex;
-        
+        public int width { get; set; }
         public double Rotate { get; set; }
-        public void setLeft(int newLeft)
+        public void setLeft(double newLeft)
         {
             left = newLeft;
         }
@@ -37,7 +38,7 @@ namespace HTEXLib.Models.HTEX
         /// <param name="underline"></param>
         /// <param name="id"></param>
         /// <param name="slideIndex"></param>
-        public HtexText(int left, int top, string fontFamily, string fontColor, double fontSize, bool isBullet,
+        public HtexText(double left, double top, string fontFamily, string fontColor, double fontSize, bool isBullet,
                          bool bold, bool italic, string underline, string id, int slideIndex)
         {
             base.fontSize = fontSize;
@@ -66,9 +67,36 @@ namespace HTEXLib.Models.HTEX
             }
             else this.underline = "none";
         }
-        public override List<HtexElement> DrawElement()
+        public override List<Item> DrawElement()
         {
-            throw new NotImplementedException();
+            if (id != null)
+            {
+                id = id.Substring(3);
+                int tryParse = 0;
+                if (int.TryParse(id, out tryParse))
+                {
+                    if (PPTShape.effectShapes.Contains(slideIndex + "_" + tryParse))
+                    {
+                        return null;
+                    }
+                }
+            }
+            return new List<Item>() { new Text() };
+          
+        }
+        public bool sameProps(HtexText other)
+        {
+            if (other == null)
+            {
+                return false;
+            }
+            return this.top == other.top
+                && this.fontSize == other.fontSize
+                && this.fontColor == other.fontColor
+                && this.italic == other.italic
+                && this.bold == other.bold
+                && this.underline == other.underline
+                && this.fontFamily == other.fontFamily;
         }
     }
 }

+ 12 - 0
HTEXLib/Models/HTEX/ShapeStyle.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace HTEXLib.Models.HTEX
+{
+    public  class ShapeStyle
+    {
+        public Border border { get; set; }
+        public Fill fill { get; set; }
+    }
+}

+ 7 - 7
HTEXLib/Models/Item.cs

@@ -44,31 +44,31 @@ namespace HTEXLib
         /// <summary>
         /// 元素绑定的链接 点击
         /// </summary>
-        public string clickLinkUrl { get; set; }
+       // public string clickLinkUrl { get; set; }
         /// <summary>
         ///  元素绑定的链接 鼠标滑过
         /// </summary>
-        public string hoverLinkUrl { get; set; }
+        //public string hoverLinkUrl { get; set; }
         /// <summary>
         /// 字号
         /// </summary>
-        public int fontScale { get; set; } = 100000;
+       // public int fontScale { get; set; } = 100000;
         /// <summary>
         /// 边距 inchPixel=72;  BottomInset= inchPixel/20;
         /// </summary>
-        public int bottom { get; set; }
+       // public int bottom { get; set; }
         /// <summary>
         /// 边距   inchPixel=72;  BottomInset= inchPixel/20;
         /// </summary>
-        public int top { get; set; }
+        //public int top { get; set; }
         /// <summary>
         /// 边距 inchPixel/10;
         /// </summary>
-        public int left { get; set; }
+       // public int left { get; set; }
         /// <summary>
         /// 边距 inchPixel/10;
         /// </summary>
-        public int right { get; set; }
+        //public int right { get; set; }
         /// <summary>
         /// 动画集合
         /// </summary>

+ 2 - 2
HTEXLib/Models/Media.cs

@@ -9,9 +9,9 @@ namespace HTEXLib
         //image 图片 video.视频 audio 音频
         public string mediaType { get; set; }
         //视频资源链接
-        public string url { get; set; }
+        public HtexBlipFill file { get; set; }
         //图片或视频音频缩略图链接
-        public string image { get; set; }
+        public HtexBlipFill  image { get; set; }
      
         public Fill fill { get; set; }
       

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

@@ -9,6 +9,8 @@ namespace HTEXLib.Models.Inner
     public static class Globals
     {
         public const int px12700 = 12700; //8000;
+        public const int px914400 = 914400;
+        public const int px96 = 96;
         public const int PercentageConstant = 100000;
         public const int FontPoint = 100;
         public const int DefaultBulletSize = 12;

+ 3 - 3
HTEXLib/Models/PPTX/PPTShape.cs

@@ -33,7 +33,7 @@ namespace HTEXLib.Models.Inner
 
         public DocumentFormat.OpenXml.Presentation.Shape element { get; set; }
 
-        public PPTShape(SlidePart slidePart, DocumentFormat.OpenXml.Presentation.Shape shape, PPTSlide slide) : base()
+        public PPTShape(OpenXmlPart slidePart, DocumentFormat.OpenXml.Presentation.Shape shape, PPTSlide slide) : base()
         {
             this.element = shape;
             this.slide = slide;
@@ -45,7 +45,7 @@ namespace HTEXLib.Models.Inner
         }
 
 
-        private void SetShapeNonVisualProperties(SlidePart slidePart, DocumentFormat.OpenXml.Presentation.Shape shape)
+        private void SetShapeNonVisualProperties(OpenXmlPart slidePart, DocumentFormat.OpenXml.Presentation.Shape shape)
         {
 
             if (shape.NonVisualShapeProperties.NonVisualDrawingProperties.HyperlinkOnClick != null)
@@ -77,7 +77,7 @@ namespace HTEXLib.Models.Inner
             base.NonVisualShapeProp = nonVisualShapeProp;
         }
 
-        private void SetShapeVisualProperties(SlidePart slidePart, DocumentFormat.OpenXml.Presentation.Shape shape)
+        private void SetShapeVisualProperties(OpenXmlPart slidePart, DocumentFormat.OpenXml.Presentation.Shape shape)
         {
 
             if (shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.PlaceholderShape != null)

+ 39 - 21
HTEXLib/Models/PPTX/PPTShapeBase.cs

@@ -20,7 +20,7 @@ namespace HTEXLib.Models.Inner
         public DocumentFormat.OpenXml.Drawing.ListStyle shapeListStyleMaster { get; set; }
         public DocumentFormat.OpenXml.Drawing.ListStyle shapeListStyleLayout { get; set; }
         public DocumentFormat.OpenXml.Drawing.TextAnchoringTypeValues VerticalAlign { get; set; }
-        public DocumentFormat.OpenXml.Packaging.SlidePart SlidePart;
+        public DocumentFormat.OpenXml.Packaging.SlidePart SlidePart { get; set; }
         public int fontScale { get; set; } = 100000;
         public double BottomInset { get; set; }
         public double TopInset { get; set; }
@@ -47,19 +47,30 @@ namespace HTEXLib.Models.Inner
             RightInset = inchPixel * 1.0 / 10;
 
         }
-        protected void SetSlideLayoutVisualShapeProperties(SlidePart slidePart, DocumentFormat.OpenXml.Presentation.Shape shape)
+        protected void SetSlideLayoutVisualShapeProperties(OpenXmlPart openXmlPart, DocumentFormat.OpenXml.Presentation.Shape shape)
         {
             VisualShapeProp = new PPTVisualPPTShapeProp();
 
-            ShapeTree shapeTree =
-                slidePart.SlideLayoutPart.SlideLayout.CommonSlideData.ShapeTree;
-
-            if (shapeTree != null)
+            if (openXmlPart is SlidePart slidePart)
             {
-                //  var layoutShape = shapeTree.GetFirstChild<Shape>();
-                GetShapesPropFromMasterPartLayout(slidePart, shape, 1);
-                fillPropertiesFromMasterShape(shape, false, false);
+                ShapeTree shapeTree = slidePart.SlideLayoutPart.SlideLayout.CommonSlideData.ShapeTree;
+                if (shapeTree != null)
+                {
+                    //  var layoutShape = shapeTree.GetFirstChild<Shape>();
+                    GetShapesPropFromMasterPartLayout(slidePart, shape, 1);
+                    fillPropertiesFromMasterShape(shape, false, false);
+                }
+            }
+            else if (openXmlPart is SlideLayoutPart layoutPart) {
+                ShapeTree shapeTree = layoutPart.SlideLayout.CommonSlideData.ShapeTree;
+                if (shapeTree != null)
+                {
+                    //  var layoutShape = shapeTree.GetFirstChild<Shape>();
+                    GetShapesPropFromMasterPartLayout(layoutPart, shape, 1);
+                    fillPropertiesFromMasterShape(shape, false, false);
+                }
             }
+          
         }
 
         private void FillFromInheritedShapes(IEnumerable<DocumentFormat.OpenXml.Presentation.Shape> masterShapes, PlaceholderShape placeholderFromShape, bool isLayout)
@@ -84,8 +95,6 @@ namespace HTEXLib.Models.Inner
                     }
             }
 
-
-
             if (placeholderFromShape.Index != null && placeholderFromShape.Index.HasValue)
             {
 
@@ -116,24 +125,33 @@ namespace HTEXLib.Models.Inner
                     }
                 }
             }
-
-
-
         }
-        private void GetShapesPropFromMasterPartLayout(SlidePart slidePart, DocumentFormat.OpenXml.Presentation.Shape shape, int slideNumber)
+        private void GetShapesPropFromMasterPartLayout(OpenXmlPart openXmlPart, DocumentFormat.OpenXml.Presentation.Shape shape, int slideNumber)
         {
 
+
             if (shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.PlaceholderShape == null) //If there is no placeholder
                 return;
-            IEnumerator<SlideLayoutPart> slPart = slidePart.SlideLayoutPart.
-                SlideMasterPart.SlideLayoutParts.GetEnumerator();
 
+            if (openXmlPart is SlidePart slidePart)
+            {
+                IEnumerator<SlideLayoutPart> slPart = slidePart.SlideLayoutPart.
+                   SlideMasterPart.SlideLayoutParts.GetEnumerator();
+                var masterShapes = slidePart.SlideLayoutPart.SlideMasterPart.SlideMaster.CommonSlideData.ShapeTree.Descendants<DocumentFormat.OpenXml.Presentation.Shape>();
+                FillFromInheritedShapes(masterShapes, shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.PlaceholderShape, false);
+                var layoutShapes = slidePart.SlideLayoutPart.SlideLayout.Descendants<DocumentFormat.OpenXml.Presentation.Shape>();
+                FillFromInheritedShapes(layoutShapes, shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.PlaceholderShape, true);
+            }
+            else if (openXmlPart is SlideLayoutPart layoutPart) {
+                IEnumerator<SlideLayoutPart> slPart = layoutPart.
+                       SlideMasterPart.SlideLayoutParts.GetEnumerator();
+                var masterShapes = layoutPart.SlideMasterPart.SlideMaster.CommonSlideData.ShapeTree.Descendants<DocumentFormat.OpenXml.Presentation.Shape>();
+                FillFromInheritedShapes(masterShapes, shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.PlaceholderShape, false);
+                var layoutShapes = layoutPart.SlideLayout.Descendants<DocumentFormat.OpenXml.Presentation.Shape>();
+                FillFromInheritedShapes(layoutShapes, shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.PlaceholderShape, true);
+            }
 
 
-            var masterShapes = slidePart.SlideLayoutPart.SlideMasterPart.SlideMaster.CommonSlideData.ShapeTree.Descendants<DocumentFormat.OpenXml.Presentation.Shape>();
-            FillFromInheritedShapes(masterShapes, shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.PlaceholderShape, false);
-            var layoutShapes = slidePart.SlideLayoutPart.SlideLayout.Descendants<DocumentFormat.OpenXml.Presentation.Shape>();
-            FillFromInheritedShapes(layoutShapes, shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.PlaceholderShape, true);
 
         }
 

+ 14 - 3
HTEXLib/Models/PPTX/PPTSlide.cs

@@ -13,7 +13,7 @@ namespace HTEXLib.Models
 {
     public class PPTSlide:PPTShapeBase
     {
-        public PPTSlide(SlidePart slidePart, int slideIndex, DefaultTextStyle defaultTextStyle, string fileName, SlideSize SlideSizes, SlideMasterPart slideMasterPart, XElement root,IEnumerable<XElement> media)
+        public PPTSlide(SlidePart slidePart, int slideIndex, DefaultTextStyle defaultTextStyle,SlideSize SlideSizes, SlideMasterPart slideMasterPart, XElement root,IEnumerable<XElement> media)
         {
             base.SlidePart = slidePart;
             base.slideMasterPart = slideMasterPart;
@@ -21,17 +21,21 @@ namespace HTEXLib.Models
             base.Media = media;
             this.advanceAfterTime = -1;
             this.slideIndex = slideIndex;
-            this.fileName = fileName;
+           // this.fileName = fileName;
             this.defaultTextStyle = defaultTextStyle;
             SlideLayoutPart = slidePart.SlideLayoutPart;
             SetShapeNonVisualProperties(slidePart);
             SetSpecificProperties(slidePart);
+            SetSpecificProperties(SlideLayoutPart);
             Id = "s1s0";
             Transition = JSONGenerator.GenerateTransitionAnimationObject(slidePart.Slide.Transition);
             Animations = new List<IAnimation>();
             AddAnimations(slidePart.Slide.Timing, Animations, SlideSizes);
         }
 
+     
+
+
         //Slide specific properties
         public DefaultTextStyle defaultTextStyle { get; set; }
         public PPTContainerShape ContainerShape { get; set; }
@@ -41,7 +45,7 @@ namespace HTEXLib.Models
         public string Id { get; set; }
         public IAnimation Transition { get; set; }
         public int slideIndex;
-        public string fileName;
+       // public string fileName;
         public int advanceAfterTime { get; set; }
         //Petco:Check if there is objects with animation.
         public void CheckAndSetAnimatableProperty(string animObjectId)
@@ -93,6 +97,13 @@ namespace HTEXLib.Models
             ContainerShape = groupShapeBuilder.GetPPTContainerShape(slidePart, this);
 
         }
+        private void SetSpecificProperties(SlideLayoutPart slideLayoutPart)
+        {
+            textStyles = SlideLayoutPart.SlideMasterPart.SlideMaster.TextStyles;
+            var groupShapeBuilder = new PPTContainerShapeBuilder();
+            ContainerShape = groupShapeBuilder.GetPPTContainerShape(slidePart, this);
+        }
+
         public void MakeShapeInvisible(String shapeId)
         {
             foreach (PPTShapeBase shape in ContainerShape.Elements)

+ 8 - 8
HTEXLib/Models/PPTX/PPTVisualPPTShapeProp.cs

@@ -33,15 +33,15 @@ namespace HTEXLib.Models.Inner
             {
                 return 1;
             }
-            else if (Extents.Cx < Globals.px12700)
+            else if (Extents.Cx < Globals.px914400)
             {
                 return
-                     Globals.px12700 *1.0 / Extents.Cx ;
+                     Globals.px914400 * 1.0 / Extents.Cx*Globals.px96 ;
             }
             else
             {
                 return
-                 Extents.Cx *1.0 / Globals.px12700;
+                 Extents.Cx *1.0* Globals.px96 / Globals.px914400;
             }
         }
 
@@ -51,15 +51,15 @@ namespace HTEXLib.Models.Inner
             {
                 return 1;
             }
-            else if (Extents.Cy < Globals.px12700)
+            else if (Extents.Cy < Globals.px914400)
             {
                 return
-                   Globals.px12700 *1.0 / Extents.Cy;
+                   Globals.px914400 * 1.0 / Extents.Cy * Globals.px96;
             }
             else
             {
                 return
-                   Extents.Cy*1.0 / Globals.px12700;
+                   Extents.Cy*1.0 * Globals.px96 / Globals.px914400;
             }
         }
 
@@ -67,13 +67,13 @@ namespace HTEXLib.Models.Inner
         {
             if (Offset == null)
                 return 0;
-            return Offset.Y *1.0 / Globals.px12700;
+            return Offset.Y *1.0 *Globals.px96 / Globals.px914400;
         }
         public double Left()
         {
             if (Offset == null)
                 return 0;
-            return Offset.X *1.0 / Globals.px12700;
+            return Offset.X *1.0 * Globals.px96 / Globals.px914400;
         }
 
 

+ 22 - 8
HTEXLib/Models/Paragraph.cs

@@ -1,3 +1,4 @@
+using HTEXLib.Models.HTEX;
 using System;
 using System.Collections.Generic;
 using System.Text;
@@ -6,17 +7,27 @@ namespace HTEXLib
 {
     public class Paragraph
     {
-         
-        public ParagraphStyle style { get; set; }
+
+        
         public Paragraph() {
-            texts = new List<Text>();
+            texts = new List<HtexText>();
         }
- 
+        /// <summary>
+        /// 
+        /// </summary>
+        public ParagraphStyle style { get; set; } = new ParagraphStyle();
+        /// <summary>
+        /// 是否有动画
+        /// </summary>
+        public bool animatable { get; set; }
         public BuChar buChar { get; set; }
-        public List<Text> texts { get; set; }
-       
+        public List<HtexText> texts { get; set; }
+        /// <summary>
+        /// 进入场景之前是否可见元素
+        /// </summary>
+        public bool invisible { get; set; }
     }
-    public class Text
+    public class Text :Item
     {
       //  public string StyleSha { get; set; }
         public string content { get; set; }
@@ -49,6 +60,9 @@ namespace HTEXLib
         // public string LeftMargin { get; set; }
         public string hori { get; set; }
         public string writing { get; set; }
-      
+        public Position position { get; set; } = new Position();
+
+        public double newTop { get; set; }
+
     }
 }

+ 24 - 10
HTEXLib/Models/Position.cs

@@ -6,19 +6,33 @@ namespace HTEXLib
 {
     public class Position
     {
-        //旋转角度
-        public double rot { get; set; } = 0;
-        //水平翻转
-        public int flipH { get; set; } = 0;
-        //垂直翻转
-        public int flipV { get; set; } = 0;
-        //x轴
+        /// <summary>
+        /// 旋转角度
+        /// </summary>
+        public double? rot { get; set; } = 0;
+        /// <summary>
+        /// 水平翻转
+        /// </summary>
+        public int? flipH { get; set; } = 0;
+        /// <summary>
+        /// 垂直翻转
+        /// </summary>
+        public int? flipV { get; set; } = 0;
+        /// <summary>
+        /// x轴
+        /// </summary>
         public double x { get; set; } = 0;
-        //y轴
+        /// <summary>
+        /// y轴
+        /// </summary>
         public double y { get; set; } = 0;
-        //宽度
+        /// <summary>
+        /// 宽度
+        /// </summary>
         public double cx { get; set; } = 0;
-        //高度
+        /// <summary>
+        /// 高度
+        /// </summary>
         public double cy { get; set; } = 0;
         ////初始坐标x
         //public Int64 ChX { get; set; } = 0;

+ 2 - 2
HTEXLib/Models/Shape.cs

@@ -8,8 +8,8 @@ namespace HTEXLib
     { 
         public string shapeType;
         public List<Paragraph> paragraph { get; set; }
-        public Fill fill { get; set; }
-        public Border border { get; set; }
+        public Fill fill { get; set; } = new Fill() { type=-1};
+        public Border border { get; set; } = new Border();
 
        
 

+ 4 - 4
HTEXTest/Program.cs

@@ -10,7 +10,7 @@ namespace HTEXTest
     {
         static void Main(string[] args)
         {
-           string path = "F:\\PRD-20191015001-test.pptx";
+            string path = "F:\\PRD-20191015001-template.pptx";
            // string path = "F:\\PRD-20191015001.pptx";
             var htexBuilder = new HtexBuilder();
             var pptSlides = htexBuilder.GetPPTSlides(path);
@@ -22,8 +22,7 @@ namespace HTEXTest
             htex.size = new HtexSize { width = width, height = height };
             foreach (PPTSlide pptSlide in pptSlides)
             {
-                var htexController = new HtexController( pptSlide,
-                                                        slideCounter, pptSlides.Count)
+                var htexController = new HtexController( pptSlide,  slideCounter, pptSlides.Count)
                 {
                     SlideWidth = width,
                     SlideHeight = height
@@ -31,7 +30,8 @@ namespace HTEXTest
                 htexController.GenerateHtex();
                 slideCounter++;
             }
-            Console.WriteLine("Hello World!");
+            htexBuilder.presentationDocument.Close();
+            GC.Collect();
         }
     }
 }