黄贺彬 преди 5 години
родител
ревизия
cc5a3d8a20

+ 5 - 5
TEAMModelOS.SDK/Helper/Common/ColorHelper/ColorHelper.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Drawing;
 using System.Text;
@@ -16,7 +16,7 @@ namespace TEAMModelOS.SDK.Helper.Common.ColorHelper
         /// </summary>
         /// <param name="rgb"></param>
         /// <returns></returns>
-        public static ColorHSV RgbToHsv(ColorRGB rgb)
+        public static ColorHSV RgbToHsv(this ColorRGB rgb)
         {
             double min, max, tmp, H, S, V;
             double R = rgb.R * 1.0f / 255, G = rgb.G * 1.0f / 255, B = rgb.B * 1.0f / 255;
@@ -65,7 +65,7 @@ namespace TEAMModelOS.SDK.Helper.Common.ColorHelper
         /// </summary>
         /// <param name="hsv"></param>
         /// <returns></returns>
-        public static ColorRGB HsvToRgb(ColorHSV hsv)
+        public static ColorRGB HsvToRgb( this ColorHSV hsv)
         {
             if (hsv.H == 360) hsv.H = 359; // 360为全黑,原因不明
             double R = 0f, G = 0f, B = 0f;
@@ -105,7 +105,7 @@ namespace TEAMModelOS.SDK.Helper.Common.ColorHelper
         /// </summary>
         /// <param name="rgb"></param>
         /// <returns></returns>
-        public static ColorHSL RgbToHsl(ColorRGB rgb)
+        public static ColorHSL RgbToHsl( this ColorRGB rgb)
         {
             double min, max, tmp, H = 0, S = 0, L = 0;
             double R = rgb.R * 1.0f / 255, G = rgb.G * 1.0f / 255, B = rgb.B * 1.0f / 255;
@@ -159,7 +159,7 @@ namespace TEAMModelOS.SDK.Helper.Common.ColorHelper
         /// </summary>
         /// <param name="hsl"></param>
         /// <returns></returns>
-        public static ColorRGB HslToRgb(ColorHSL hsl)
+        public static ColorRGB HslToRgb( this ColorHSL hsl)
         {
             var l = hsl.L;
             var s = hsl.S;

+ 12 - 1
TEAMModelOS.Service/Models/PowerPoint/Fill.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Text;
 
@@ -6,6 +6,10 @@ namespace HiTeachCC.Model.PowerPoint
 {
     public class Fill
     {
+
+        public Fill() {
+            gradColor = new List<string>();
+        }
         /// <summary>
         /// [a:noFill, solidFill, gradFill, blipFill, pattFill, grpFill]
         ///0,无填充 1.纯色填充 2.渐变填充 3.图片或纹理填充 4.图案填充
@@ -14,6 +18,13 @@ namespace HiTeachCC.Model.PowerPoint
         public string Color { get; set; }
         public string Image { get; set; }
         public FillStyle FillStyle { get; set; }
+       
+        public string SvgText { get; set; }
+        public string HtmlText { get; set; }
+        //渐变填充投射方向
+        public double Rot { get; set; }
+        //渐变填充 颜色列表
+        public List<string> gradColor { get; set; }
 
     }
     /// <summary>

+ 6 - 6
TEAMModelOS.Service/Models/PowerPoint/Position.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Text;
 
@@ -7,19 +7,19 @@ namespace HiTeachCC.Model.PowerPoint
     public class Position
     {
         //旋转角度
-        public Int64 Rot { get; set; } = 0;
+        public double Rot { get; set; } = 0;
         //水平翻转
         public int FlipH { get; set; } = 0;
         //垂直翻转
         public int FlipV { get; set; } = 0;
         //x轴
-        public Int64 X { get; set; } = 0;
+        public double X { get; set; } = 0;
         //y轴
-        public Int64 Y { get; set; } = 0;
+        public double Y { get; set; } = 0;
         //宽度
-        public Int64 Cx { get; set; } = 0;
+        public double Cx { get; set; } = 0;
         //高度
-        public Int64 Cy { get; set; } = 0;
+        public double Cy { get; set; } = 0;
         ////初始坐标x
         //public Int64 ChX { get; set; } = 0;
         ////初始坐标Y

+ 1 - 1
TEAMModelOS.Service/Services/PowerPoint/Implement/PowerPointHelper.cs

@@ -1,4 +1,4 @@
-using DocumentFormat.OpenXml;
+using DocumentFormat.OpenXml;
 using DocumentFormat.OpenXml.Drawing;
 using DocumentFormat.OpenXml.Packaging;
 using DocumentFormat.OpenXml.Presentation;

+ 1 - 1
TEAMModelOS.Service/Services/PowerPoint/Implement/PowerPointService.cs

@@ -1,4 +1,4 @@
-using DocumentFormat.OpenXml;
+using DocumentFormat.OpenXml;
 using DocumentFormat.OpenXml.Drawing;
 using DocumentFormat.OpenXml.Office2010.Drawing;
 using DocumentFormat.OpenXml.Packaging;

+ 656 - 14
TEAMModelOS.Service/Services/PowerPoint/Implement/ShapeGenerator.cs

@@ -6,6 +6,7 @@ using HiTeachCC.Service.PowerPoint.Interface;
 using Microsoft.AspNetCore.Http;
 using System;
 using System.Collections.Generic;
+using System.Drawing;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -15,6 +16,7 @@ using System.Xml.XPath;
 using TEAMModelOS.SDK.Context.Constant;
 using TEAMModelOS.SDK.Context.Constant.Common;
 using TEAMModelOS.SDK.Context.Exception;
+using TEAMModelOS.SDK.Helper.Common.ColorHelper;
 using TEAMModelOS.SDK.Helper.Common.JsonHelper;
 using TEAMModelOS.SDK.Helper.Common.StringHelper;
 using TEAMModelOS.SDK.Helper.Security.ShaHash;
@@ -23,6 +25,7 @@ using TEAMModelOS.SDK.Module.AzureBlob.Interfaces;
 using TEAMModelOS.Service.Models.PowerPoint.Inner;
 using ColorMap = DocumentFormat.OpenXml.Presentation.ColorMap;
 using Fill = HiTeachCC.Model.PowerPoint.Fill;
+using Position = HiTeachCC.Model.PowerPoint.Position;
 
 namespace HiTeachCC.Service.PowerPoint.Implement
 {
@@ -433,13 +436,661 @@ namespace HiTeachCC.Service.PowerPoint.Implement
                // type = slideLayoutSpNode.TryGetValue"p:nvSpPr", "p:nvPr", "p:ph", "attrs", "type"]);
                 if (type ==null)
                 {
-                    type = slideMasterSpNode.GetTextByPath("p:nvSpPr/p:nvPr/p:ph/@type");
+                    if (slideMasterSpNode != null) {
+                        type = slideMasterSpNode.GetTextByPath("p:nvSpPr/p:nvPr/p:ph/@type");
+                    }
                     // type = getTextByPathList(slideMasterSpNode, ["p:nvSpPr", "p:nvPr", "p:ph", "attrs", "type"]);
                 }
             }
+           string  s =  GenShape(node, slideLayoutSpNode, slideMasterSpNode, id, name, idx, type, order, warpObj);
+            throw new NotImplementedException();
+        }
+
+        private string GenShape(XmlNode node, XmlNode slideLayoutSpNode, XmlNode slideMasterSpNode, XmlNode id, XmlNode name, XmlNode idx, XmlNode type, XmlNode order, WarpObj warpObj)
+        {
+            var xfrmList = "p:spPr/a:xfrm";
+            var slideXfrmNode = node.GetTextByPath(xfrmList);
+            var slideLayoutXfrmNode = slideLayoutSpNode.GetTextByPath( xfrmList);
+            var slideMasterXfrmNode = slideMasterSpNode.GetTextByPath( xfrmList);
+            var result = "";
+            var shpId = node.GetTextByPath("/@order");
+            var shapType = node.GetTextByPath("p:spPr/a:prstGeom/@prst");
+            var custShapType = node.GetTextByPath("p:spPr/a:custGeom");
+
+            var isFlipV = 0;
+            var isFlipH = 0;
+            if (slideXfrmNode.GetTextByPath("@flipV") != null && slideXfrmNode.GetTextByPath("@flipV").Value == "1")
+            {//   if ( getTextByPathList(slideXfrmNode, ["attrs", "flipV"]) === "1" || getTextByPathList(slideXfrmNode, ["attrs", "flipH"]) === "1")
+                isFlipV = 1;
+            }
+            if (slideXfrmNode.GetTextByPath("@flipH") != null && slideXfrmNode.GetTextByPath("@flipH").Value == "1")
+            {
+                isFlipH = 1;
+            }
+            //rotate
+            var rotate = AngleToDegrees(slideXfrmNode.GetTextByPath("@rot"));
+
+            //console.log("rotate: "+rotate);
+            double txtRotate=0.0;
+            var txtXframeNode = node.GetTextByPath("p:txXfrm/@rot");
+            if (txtXframeNode !=  null)
+            {
+                txtRotate = AngleToDegrees(txtXframeNode) + 90;
+            }
+            else
+            {
+                txtRotate = rotate;
+            }
+            if (shapType != null || custShapType != null) {
+
+           
+                var x = int.Parse(slideXfrmNode.GetTextByPath("a:off/@x").Value) * px96 / px914400;
+                var y = int.Parse(slideXfrmNode.GetTextByPath("a:off/@y").Value) * px96 / px914400;
+                var w = int.Parse(slideXfrmNode.GetTextByPath("a:ext/@cx").Value) * px96 / px914400;
+                var h = int.Parse(slideXfrmNode.GetTextByPath("a:ext/@cy").Value) * px96 / px914400;
+                Position  position= GetPosition(slideXfrmNode, null, null);
+                position.Cx = w;
+                position.Cy = h;
+                position.Rot = rotate;
+                position.FlipH = isFlipH;
+                position.FlipV = isFlipV;
+                
+                //result += "<svg class='drawing' _id='" + id + "' _idx='" + idx + "' _type='" + type + "' _name='" + name +
+                //        "' style='" +
+                //            getPosition(slideXfrmNode, null, null) +
+                //            getSize(slideXfrmNode, null, null) +
+                //            " z-index: " + order + ";" +
+                //            "transform: rotate(" + rotate + "deg);" +
+                //            "'>";
+                //result += "<defs>";
+                // Fill Color
+                var fillColor = GetShapeFill(node, true, warpObj);
+                var grndFillFlg = false;
+                var imgFillFlg = false;
+                var clrFillType = GetFillType(node.GetTextByPath("p:spPr"));
+                /////////////////////////////////////////                    
+                if (clrFillType == "GRADIENT_FILL")
+                {
+                    grndFillFlg = true;
+                    var color_arry = fillColor.gradColor;
+                    var angl = fillColor.Rot;
+
+                    var svgGrdnt = GetSvgGradient(w, h, angl, color_arry, shpId);
+                    //fill="url(#linGrd)"
+                    result += svgGrdnt;
+                }
+                else if (clrFillType == "PIC_FILL")
+                {
+                    imgFillFlg = true;
+                    var svgBgImg = GetSvgImagePattern(fillColor.Image, shpId.Value);
+                    //fill="url(#imgPtrn)"
+                    //console.log(svgBgImg)
+                    result += svgBgImg;
+                }
+                else
+                {
+                    if (clrFillType != "SOLID_FILL" && clrFillType != "PATTERN_FILL" &&
+                    (shapType.Value == "arc" ||
+                    shapType.Value == "bracketPair" ||
+                    shapType.Value == "bracePair" ||
+                    shapType.Value == "leftBracket" ||
+                    shapType.Value == "leftBrace" ||
+                    shapType.Value == "rightBrace" ||
+                    shapType.Value == "rightBracket"))
+                    { //Temp. solution  - TODO
+                        fillColor.HtmlText = "none";
+                    }
+                }
+                // Border Color
+                var border = GetBorder(node, true, "shape");
+
+                var headEndNodeAttrs = node.GetTextByPath("p:spPr/a:ln/a:headEnd");
+                var tailEndNodeAttrs = node.GetTextByPath("p:spPr/a:ln/a:tailEnd");
+                // type: none, triangle, stealth, diamond, oval, arrow
+
+                if ((headEndNodeAttrs !=null&& (headEndNodeAttrs.GetTextByPath("@type").Value == "triangle" || (headEndNodeAttrs.GetTextByPath("@type").Value == "arrow")) ||
+                    (tailEndNodeAttrs != null && (tailEndNodeAttrs.GetTextByPath("@type").Value == "triangle" || (tailEndNodeAttrs.GetTextByPath("@type").Value == "arrow")))))
+                {
+                    var triangleMarker = "<marker id='markerTriangle_" + shpId + "' viewBox='0 0 10 10' refX='1' refY='5' markerWidth='5' markerHeight='5' stroke='" + border.Color + "' fill='" + border.Color +
+                                    "' orient='auto-start-reverse' markerUnits='strokeWidth'><path d='M 0 0 L 10 5 L 0 10 z' /></marker>";
+                    result += triangleMarker;
+                }
+                result += "</defs>";
+            }
             throw new NotImplementedException();
         }
+        public   Border GetBorder(XmlNode node, bool isSvgMode, string bType)
+        {
+
+            Border border = new Border();
+            string cssText = "";
+            XmlNode lineNode = null;
+            if (bType == "shape")
+            {
+                cssText = "border: ";
+                lineNode = PowerPointHelper.GetTextByPath(node, "p:spPr/a:ln");// node["p:spPr"]["a:ln"];
+            }
+            else if (bType == "text")
+            {
+                cssText = "";
+                lineNode = PowerPointHelper.GetTextByPath(node, "p:rPr/a:ln");// node["a:rPr"]["a:ln"];
+
+            }
+
+            // Border width: 1pt = 12700, default = 0.75pt
+            var borderWidth = int.Parse(PowerPointHelper.GetTextByPath(lineNode, "@w").Value) / 12700;
+            if (PowerPointHelper.GetTextByPath(lineNode, "@w") != null  || borderWidth < 1)
+            {
+                cssText += "1pt ";
+            }
+            else
+            {
+                cssText += borderWidth + "pt ";
+            }
+            // Border type
+            var borderType = PowerPointHelper.GetTextByPath(lineNode, "a:prstDash/@val").Value;
+            var strokeDasharray = "0";
+            switch (borderType)
+            {
+                case "solid":
+                    cssText += "solid";
+                    strokeDasharray = "0";
+                    break;
+                case "dash":
+                    cssText += "dashed";
+                    strokeDasharray = "5";
+                    break;
+                case "dashDot":
+                    cssText += "dashed";
+                    strokeDasharray = "5, 5, 1, 5";
+                    break;
+                case "dot":
+                    cssText += "dotted";
+                    strokeDasharray = "1, 5";
+                    break;
+                case "lgDash":
+                    cssText += "dashed";
+                    strokeDasharray = "10, 5";
+                    break;
+                case "lgDashDotDot":
+                    cssText += "dashed";
+                    strokeDasharray = "10, 5, 1, 5, 1, 5";
+                    break;
+                case "sysDash":
+                    cssText += "dashed";
+                    strokeDasharray = "5, 2";
+                    break;
+                case "sysDashDot":
+                    cssText += "dashed";
+                    strokeDasharray = "5, 2, 1, 5";
+                    break;
+                case "sysDashDotDot":
+                    cssText += "dashed";
+                    strokeDasharray = "5, 2, 1, 5, 1, 5";
+                    break;
+                case "sysDot":
+                    cssText += "dotted";
+                    strokeDasharray = "2, 5";
+                    break;
+                case null:
+                //console.log(borderType);
+                default:
+                    cssText += "solid";
+                    strokeDasharray = "0";
+                    break;
+            }
+            // Border color
+            var borderColor = PowerPointHelper.GetTextByPath(lineNode, "a:solidFill/:srgbClr/@val").Value;
+            if (borderColor == null)
+            {
+                var schemeClrNode = PowerPointHelper.GetTextByPathList(lineNode, "a:solidFill/a:schemeClr");
+                if (schemeClrNode != null)
+                {
+                    var schemeClr = PowerPointHelper.GetTextByPath(lineNode, "a:solidFill/a:schemeClr/@val");
+                    borderColor = GetSchemeColorFromTheme(schemeClr.Value, null);
+                }
+            }
+
+            // 2. drawingML namespace
+            if (borderColor == null)
+            {
+                var schemeClrNode = PowerPointHelper.GetTextByPathList(node, "p:style/a:lnRef/a:schemeClr");
+                if (schemeClrNode != null)
+                {
+                    var schemeClr = PowerPointHelper.GetTextByPath(node, "p:style/a:lnRef/a:schemeClr/@val");
+                    borderColor = GetSchemeColorFromTheme(schemeClr.Value, null);
+                }
+                if (borderColor != null)
+                {
+                    var shade = PowerPointHelper.GetTextByPath(node, "p:style/a:lnRef/a:schemeClr/a:shade/@val").Value;
+                    if (shade != null)
+                    {
+                      int    shaded =  int.Parse(shade) / 100000 ;
+                        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();
+                        borderColor =ColorTranslator.ToHtml(Color.FromArgb(colorRGB.R, colorRGB.G, colorRGB.B));
+                       // borderColor = color.hex.replace("#", "");
+                    }
+                }
+
+            }
+
+            if (borderColor == null)
+            {
+                if (isSvgMode)
+                {
+                    borderColor = "none";
+                }
+                else
+                {
+                    borderColor = "#000";
+                }
+            }
+            else
+            {
+                borderColor = "#" + borderColor;
+
+            }
+            cssText += " " + borderColor + " ";
+
+
+            if (isSvgMode)
+            {
+                return new Border { Color = borderColor, Width = borderWidth, Type = borderType, Stroke = strokeDasharray };
+            }
+            else
+            {
+                return border;
+            }
+        }
+
+        public static string GetSvgImagePattern(string fillColor, string shpId)
+        {
+            var ptrn = "<pattern id=\"imgPtrn_" + shpId + "\"patternContentUnits=\"objectBoundingBox\"  width=\"1\" height=\"1\">";// '<pattern id="imgPtrn_' + shpId + '"  patternContentUnits="objectBoundingBox"  width="1" height="1">';
+            ptrn += "<image  xlink:href=\"" + fillColor + "\"preserveAspectRatio=\"none\" width=\"1\" height=\"1\"></image>";// '<image  xlink:href="' + fillColor + '" preserveAspectRatio="none" width="1" height="1"></image>';
+            ptrn += "</pattern>";// '';
+            return ptrn;
+        }
+        private  object GetSvgGradient(double w, double h, double angl, List<string> color_arry, XmlNode shpId)
+        {
+
+            var stopsArray = GetMiddleStops(color_arry.Count - 2);
+
+            var svgAngle = "";
+            double svgHeight = h;
+            double svgWidth = w;
+            string svg = "";
+            List<double> xy_ary = SVGangle(angl, svgHeight, svgWidth);
+            double x1 = xy_ary[0];
+            double y1 = xy_ary[1];
+            double x2 = xy_ary[2];
+            double y2 = xy_ary[3];
+
+            var sal = stopsArray.Count;
+            double sr = sal < 20 ? 100 : 1000;
+            svgAngle = " gradientUnits=\"userSpaceOnUse\" x1=\"" + x1 + "%\" y1=\"" + y1 + "%\" x2=\"" + x2 + "%\" y2=\"" + y2 + "%\"";
+            svgAngle = "<linearGradient id=\"linGrd_" + shpId + "\"" + svgAngle + ">\n";
+            svg += svgAngle;
+
+            for (var i = 0; i < sal; i++)
+            {
+                svg += "<stop offset=\"" +(System. Math.Round(double.Parse(stopsArray[i])) / 100 * sr) / sr + "\" stop-color=\"" + color_arry[i] + "\"";
+                svg += "/>\n";
+            }
+
+            svg += "</linearGradient>\n" + "";
+
+            return svg;
+        }
+        private static List<double> SVGangle(double deg, double svgHeight, double svgWidth)
+        {
+            double w = svgWidth;
+            double h = svgHeight;
+            double ang = deg;
+            double o = 2;
+            double n = 2;
+            double wc = w / 2;
+            double hc = h / 2;
+            double tx1 = 2;
+            double ty1 = 2;
+            double tx2 = 2;
+            double ty2 = 2;
+            double k = (((ang % 360) + 360) % 360);
+            double j = (360 - k) * System. Math.PI / 180;
+            double i = System.Math.Tan(j);
+            double l = hc - i * wc;
+
+            if (k == 0)
+            {
+                tx1 = w;
+                ty1 = hc;
+                tx2 = 0;
+                ty2 = hc;
+            }
+            else if (k < 90)
+            {
+                n = w;
+                o = 0;
+            }
+            else if (k == 90)
+            {
+                tx1 = wc;
+                ty1 = 0;
+                tx2 = wc;
+                ty2 = h;
+            }
+            else if (k < 180)
+            {
+                n = 0;
+                o = 0;
+            }
+            else if (k == 180)
+            {
+                tx1 = 0;
+                ty1 = hc;
+                tx2 = w;
+                ty2 = hc;
+            }
+            else if (k < 270)
+            {
+                n = 0;
+                o = h;
+            }
+            else if (k == 270)
+            {
+                tx1 = wc;
+                ty1 = h;
+                tx2 = wc;
+                ty2 = 0;
+            }
+            else
+            {
+                n = w;
+                o = h;
+            }
+            // AM: I could not quite figure out what m, n, and o are supposed to represent from the original code on visualcsstools.com.
+            var m = o + (n / i);
+            tx1 = tx1 == 2 ? i * (m - l) / (System.Math.Pow(i, 2) + 1) : tx1;
+            ty1 = ty1 == 2 ? i * tx1 + l : ty1;
+            tx2 = tx2 == 2 ? w - tx1 : tx2;
+            ty2 = ty2 == 2 ? h - ty1 : ty2;
+            double x1 = System.Math.Round(tx2 / w * 100 * 100) / 100;
+            double y1 = System.Math.Round(ty2 / h * 100 * 100) / 100;
+            double x2 = System.Math.Round(tx1 / w * 100 * 100) / 100;
+            double y2 = System.Math.Round(ty1 / h * 100 * 100) / 100;
+            return new List<double> { x1 , y1 , x2 , y2  };
+        }
+        private List<string>  GetMiddleStops(int s)
+        {
+            var sArry = new List<string> { "0%" };
+
+            
+            if (s == 0)
+            {
+                return sArry;
+            }
+            else
+            {
+                for (int i = s; i < 0; i--)
+                {
+                    var middleStop = 100 - ((100 / (s + 1)) * (i + 1)); // AM: Ex - For 3 middle stops, progression will be 25%, 50%, and 75%, plus 0% and 100% at the ends.
+                    var middleStopString = middleStop + "%";
+
+                    sArry.Add(middleStopString);
+                    //  sArry.splice(-1, 0, middleStopString);
+
+                }
+                // AM: add into stopsArray before 100%
+            }
+            sArry.Add("100%");
+            return sArry;
+        }
+        public   Fill GetShapeFill(XmlNode node, bool isSvgMode, WarpObj warpObj)
+        {
+
+            // 1. presentationML
+            // p:spPr/ [a:noFill, solidFill, gradFill, blipFill, pattFill, grpFill]
+            // From slide
+            //Fill Type:
+            //console.log("ShapeFill: ", node)
+            var fillType = GetFillType(PowerPointHelper.GetTextByPath(node, "p:spPr"));
+            Fill fill = new Fill();
+            if (fillType == "NO_FILL")
+            {
+                fill.SvgText = "node";
+                fill.Type = 0;
+                fill.HtmlText = "background-color: initial;";
+                //return isSvgMode ? "none" : "background-color: initial;";
+            }
+            else if (fillType == "SOLID_FILL")
+            {
+                XmlNode shpFill = PowerPointHelper.GetTextByPath(node, "p:spPr/a:solidFill");// node["p:spPr"]["a:solidFill"];
+                fill = GetSolidFill(shpFill);
+            }
+            else if (fillType == "GRADIENT_FILL")
+            {
+                var shpFill = PowerPointHelper.GetTextByPath(node, "p:spPr/a:gradFill");// node["p:spPr"]["a:gradFill"];
+                // fillColor = GetSolidFill(shpFill);
+                fill = GetGradientFill(shpFill);
+                //console.log("shpFill",shpFill,grndColor.color)
+            }
+            else if (fillType == "PATTERN_FILL")
+            {
+                var shpFill = PowerPointHelper.GetTextByPath(node, "p:spPr/a:pattFill");// node["p:spPr"]["a:pattFill"];
+                fill = GetPatternFill(shpFill);
+            }
+            else if (fillType == "PIC_FILL")
+            {
+                var shpFill = PowerPointHelper.GetTextByPath(node, "p:spPr/a:blipFill"); //node["p:spPr"]["a:blipFill"];
+                fill = GetPicFill("slideBg", shpFill, warpObj);
+            }
+
+
+            // 2. drawingML namespace
+            if (fill == null)
+            {
+                var clrName = PowerPointHelper.GetTextByPath(node, "p:style/a:fillRef");
+                fill = GetSolidFill(clrName);
+            }
+
+            if (fill != null)
+            {
+                if (fillType == "GRADIENT_FILL")
+                {
+                    if (isSvgMode)
+                    {
+                        // console.log("GRADIENT_FILL color", fillColor.color[0])
+                        return fill;
+                    }
+                    else
+                    {
+                        var colorAry = fill.Color;
+                        var rot = fill.Rot;
 
+                        var bgcolor = "background: linear-gradient(" + rot + "deg,";
+                        for (var i = 0; i < colorAry.Length; i++)
+                        {
+                            if (i == colorAry.Length - 1)
+                            {
+                                bgcolor += colorAry[i] + ");";
+                            }
+                            else
+                            {
+                                bgcolor += colorAry[i] + ", ";
+                            }
+
+                        }
+                        return fill;
+                    }
+                }
+                else if (fillType == "PIC_FILL")
+                {
+                    if (isSvgMode)
+                    {
+                        return fill;
+                    }
+                    else
+                    {
+
+                        return fill;
+                    }
+                }
+                else
+                {
+                    if (isSvgMode)
+                    {
+                     //   var color = new colz.Color(fill);
+                       // fill = color.rgb.toString();
+
+                        return fill;
+                    }
+                    else
+                    {
+                        //console.log(node,"fillColor: ",fillColor,"fillType: ",fillType,"isSvgMode: ",isSvgMode)
+                        return fill;
+                    }
+                }
+            }
+            else
+            {
+                if (isSvgMode)
+                {
+                    return fill;
+                }
+                else
+                {
+                    return fill;
+                }
+
+            }
+        }
+        private   Fill GetPatternFill(XmlNode node)
+        {
+            Fill fill = new Fill { Type=4};
+            var fgClr = PowerPointHelper.GetTextByPath(node, "a:fgClr");
+            fill = GetSolidFill(fgClr);
+            return fill;
+        }
+        private   Fill GetGradientFill(XmlNode node )
+        {
+
+            XmlNodeList gsLst = PowerPointHelper.GetTextByPathList(node, "a:gsLst/a:gs");// node["a:gsLst"]["a:gs"];
+            //get start color
+            var color_ary = new List<string>();
+            var tint_ary = new string[] { };
+            for (int i = 0; i < gsLst.Count; i++)
+            {
+                var lo_color = GetSolidFill(gsLst[i]);
+                if (gsLst[i].GetTextByPath("a:srgbClr") != null)
+                {
+                    var mod = PowerPointHelper.GetTextByPath(node, "a:srgbClr/a:lumMod/@val");
+                    var off = PowerPointHelper.GetTextByPath(node, "a:srgbClr/a:lumOff/@val");
+                    double lumMod = 1.0;
+                    double lumOff = 1.0;
+                    if (mod!=null)
+                    {
+                        lumMod = double.Parse(mod.Value) /100000;
+                    }
+                    if (off!=null)
+                    {
+                        lumOff = double.Parse(off.Value) / 100000;
+                    }
+                    //console.log([lumMod, lumOff]);
+                    lo_color = ApplyLumModify(lo_color, lumMod, lumOff);
+                }
+                else if (gsLst[i].GetTextByPath("a:schemeClr") != null)
+                { 
+                    //a:schemeClr
+                    var mod = PowerPointHelper.GetTextByPath(node, "a:schemeClr/a:lumMod/@val");
+                    var off = PowerPointHelper.GetTextByPath(node, "a:schemeClr/a:lumOff/@val");
+                    double lumMod = 1.0;
+                    double lumOff = 1.0;
+                    if (mod != null)
+                    {
+                        lumMod = double.Parse(mod.Value) / 100000;
+                    }
+                    if (off != null)
+                    {
+                        lumOff = double.Parse(off.Value) / 100000;
+                    }
+                    //console.log([lumMod, lumOff]);
+                    lo_color = ApplyLumModify(lo_color, lumMod, lumOff);
+                }
+                color_ary.Add(lo_color.Color);
+            }
+            //get rot
+            var lin = PowerPointHelper.GetTextByPathList(node, "a:lin");// node["a:lin"];
+            double rot = 0;
+            if (lin != null)
+            {
+                rot = AngleToDegrees(PowerPointHelper.GetTextByPath(node, "a:lin/@ang")) + 90;
+            }
+            return new Fill()
+            {
+                Type = 2,
+                gradColor = color_ary,
+                Rot = rot
+            };
+        }
+        private static Fill ApplyLumModify(Fill rgbStr, double factor, double offset)
+        {
+            Color color = ColorTranslator.FromHtml("#" + rgbStr.Color);
+            ColorRGB  RGB = new ColorRGB(color.R,color.G,color.B);
+            ColorHSL  HSL=  ColorHelper.RgbToHsl(RGB);
+            HSL.L= HSL.L * (1 + offset);
+            RGB = ColorHelper.HslToRgb(HSL);
+            color= Color.FromArgb(RGB.R, RGB.G, RGB.B);
+            rgbStr.Color=ColorTranslator.ToHtml(color).Replace("#","");
+            return rgbStr;
+        }
+        public static Position GetPosition(XmlNode slideSpNode, XmlNode slideLayoutSpNode, XmlNode slideMasterSpNode)
+        {
+
+            XmlNode off = null;
+            double x, y;
+
+            if (slideSpNode != null)
+            {
+                off = PowerPointHelper.GetTextByPath(slideSpNode, "p:spPr/a:xfrm/a:off");
+            }
+            else if (slideLayoutSpNode != null)
+            {
+                off = PowerPointHelper.GetTextByPath(slideLayoutSpNode, "p:spPr/a:xfrm/a:off");
+            }
+            else if (slideMasterSpNode != null)
+            {
+                off = PowerPointHelper.GetTextByPath(slideMasterSpNode, "p:spPr/a:xfrm/a:off");
+            }
+            x = double.Parse(PowerPointHelper.GetTextByPath(off, "@x").Value) * px96 / px914400;
+            y = double.Parse(PowerPointHelper.GetTextByPath(off, "@y").Value) * px96 / px914400;
+            return new Position()
+            {
+                X = x,
+                Y = y
+            };
+
+            //if (off == null)
+            //{
+            //    return "";
+            //}
+            //else
+            //{
+
+
+            //    //  return (IsNaN(x) || IsNaN(y)) ? "" : "top:" + y + "px; left:" + x + "px;";
+            //}
+
+        }
+        private  double  AngleToDegrees(XmlNode angle)
+        {
+            if ( angle == null)
+            {
+                return 0;
+            }
+            return System.Math.Round(double.Parse(angle.Value) / 60000);
+        }
         private Fill GetSlideBackgroundFill(XmlNode slideContent ,XmlNode slideLayoutContent  , XmlNode slideMasterContent , WarpObj warpObj) {
             var bgPr = slideContent.GetTextByPath("p:sld/p:cSld/p:bg/p:bgPr");
             var bgRef = slideContent.GetTextByPath("p:sld/p:cSld/p:bg/p:bgRef");
@@ -519,10 +1170,10 @@ namespace HiTeachCC.Service.PowerPoint.Implement
             {
                 return null;
             }
-          //  var imgArrayBuffer = warpObj.zip.GetTextByPath(imgPath).Value.asArrayBuffer();
+            //  var imgArrayBuffer = warpObj.zip.GetTextByPath(imgPath).Value.asArrayBuffer();
             //var imgMimeType = GetMimeType(imgExt);
             //img = "data:" + imgMimeType + ";base64," + base64ArrayBuffer(imgArrayBuffer);
-            return   null;
+            return new Fill { Type = 3, Image = img };
 
         }
 
@@ -605,16 +1256,7 @@ namespace HiTeachCC.Service.PowerPoint.Implement
             }
             return bgcolor;
         }
-        public   double AngleToDegrees(XmlNode angle)
-        {
-            if (angle.Value == "" || angle == null)
-            {
-                return 0;
-            }
-            int.TryParse(angle.Value, out int angleInt);
-            double a = angleInt / 60000;
-            return System.Math.Round(a);
-        }
+    
         private string HexToRgbNew(string bgColor)
         {
             //var arrBuff = new ArrayBuffer(4);
@@ -694,7 +1336,7 @@ namespace HiTeachCC.Service.PowerPoint.Implement
                 return null;
             }
 
-            Fill fill = new Fill() { Color = "FFF" };
+            Fill fill = new Fill() { Color = "FFF" ,Type=1  };
 
             if (PowerPointHelper.GetTextByPath(node, "a:srgbClr").Value != null)
             {