瀏覽代碼

完成表格解析,包含表格模型,表格样式,Tr样式,Td样式,跨行跨列,文字样式,文字信息等。

CrazyIter 5 年之前
父節點
當前提交
8c96147345

+ 1 - 0
TEAMModelOS.Service/Models/PowerPoint/Border.cs

@@ -14,5 +14,6 @@ namespace HiTeachCC.Model.PowerPoint
         /// 描边
         /// </summary>
         public string Stroke{ get; set; }
+        public string Dir { get; set; }
     }
 }

+ 24 - 1
TEAMModelOS.Service/Models/PowerPoint/Chart.cs

@@ -6,6 +6,29 @@ namespace HiTeachCC.Model.PowerPoint
 {
     public class Chart : Item
     {
-        
+        /// <summary>
+        ///  barChart
+        ///     簇状柱形图 clustered
+        ///     堆积柱形图 stacked
+        ///     百分比堆积柱形图 percentStacked
+        ///  bar3DChart
+        ///     三维堆积柱形图 stacked
+        ///     三维簇状柱形图 clustered
+        ///     三维百分比堆积柱形图 percentStacked
+        ///     三维柱形图 standard
+        ///  lineChart
+        ///  合并
+        ///     折线图 standard
+        ///     带数据标记的折线图 standard 
+        ///  合并
+        ///     堆积折线图 stacked
+        ///     带标记的堆积折线图 stacked  <c:layout>不为空
+        ///  合并 
+        ///     百分比堆积折线图 percentStacked
+        ///     带数据标记的百分比堆积折线图 percentStacked
+        ///  line3DChart
+        ///     三维折线图 standard
+        /// </summary>
+        public string ChartType { get; set; }
     }
 }

+ 1 - 1
TEAMModelOS.Service/Models/PowerPoint/Inner/WarpObj.cs

@@ -17,7 +17,7 @@ namespace TEAMModelOS.Service.Models.PowerPoint.Inner
         public XmlNode slideLayoutContent { get; set; }
         public XmlNode slideMasterContent { get; set; }
         public XmlNode themeContent { get; set; }
-        
+        public XmlNode tableStyles { get; set; }
     }
 
 

+ 1 - 1
TEAMModelOS.Service/Models/PowerPoint/Item.cs

@@ -6,7 +6,7 @@ namespace HiTeachCC.Model.PowerPoint
 {
     public abstract class Item
     {
-        // Sp  CxnSp Media Group
+        // Sp  CxnSp Media Group  Table Chart
         public string Type { get; set; }
         public Position Position { get; set; }
       //  public string Xml { get; set; }

+ 21 - 3
TEAMModelOS.Service/Models/PowerPoint/Table.cs

@@ -6,19 +6,37 @@ namespace HiTeachCC.Model.PowerPoint
 {
     public class Table :Item
     {
-        public Border Border { get; set; }
-        public Fill Fill { get; set; }
+        public Table() {
+            Tr = new List<Tr>();
+        }
+        //内容排版方向 左书写 右书写
+        public string Dir { get; set; }
+        public string BorderCollapse { get; set; } = "collapse";
+       // public Border Border { get; set; }
+       // public Fill Fill { get; set; }
         public List<Tr> Tr { get; set; }
     }
 
     public class Tr {
+        public Tr()
+        {
+            Td = new List<Td>();
+        }
+        public Fill Fill { get; set; }
+        public  double height { get; set; }
         public List<Td> Td { get; set; }
+        public List<Border> Borders { get; set; }
 
     }
     public class Td
     {
+        public double width { get; set; }
+        public Fill Fill { get; set; }
         public int Rowspan { get; set; }
         public int Colspan { get; set; }
-        public Paragraph Paragraph { get; set; }
+
+        public int VMerge { get; set; }
+        public int HMerge { get; set; }
+        public List<Paragraph> Paragraphs { get; set; }
     }
 }

+ 302 - 10
TEAMModelOS.Service/Services/PowerPoint/Implement/ShapeGenerator.cs

@@ -124,7 +124,7 @@ namespace HiTeachCC.Service.PowerPoint.Implement
                 var node = xdoc.GetTextByPath("//pkg:part[@pkg:name='/ppt/slides/slide" + (i + 1) + ".xml']");
                 string filename = node.GetTextByPath("@pkg:name").Value;
                 //处理当前页的幻灯片
-                Slide slide = await ProcessSingleSlide(xdoc, node, filename, i, slideSize, themeContent);
+                Slide slide = await ProcessSingleSlide(xdoc, node, filename, i, slideSize, themeContent, tableStyles);
                 slides.Add(slide);
               //  post_ary.Add(new Dictionary<string, object> { { "slide", slideHtml } });
                // post_ary.Add(new Dictionary<string, object> { { "progress-update", (i + 1) * 100 / numOfSlides } });
@@ -154,7 +154,7 @@ namespace HiTeachCC.Service.PowerPoint.Implement
             return cssText;
         }
 
-        public async Task<Slide> ProcessSingleSlide(XmlDocument xdoc, XmlNode xnode, string sldFileName, int index, dynamic slideSize, XmlNode themeContent)
+        public async Task<Slide> ProcessSingleSlide(XmlDocument xdoc, XmlNode xnode, string sldFileName, int index, dynamic slideSize, XmlNode themeContent, XmlNode tableStyles)
         {
 
             var resName = sldFileName.Replace("slides/slide", "slides/_rels/slide") + ".rels";
@@ -283,7 +283,8 @@ namespace HiTeachCC.Service.PowerPoint.Implement
                 masterResObj = masterResObj,
                 slideLayoutContent = slideLayoutContent,
                 slideMasterContent = slideMasterContent,
-                themeContent = themeContent
+                themeContent = themeContent,
+                tableStyles=tableStyles
             };
             var bgColor = await GetSlideBackgroundFill(slideContent, index, warpObj);
             string result = "<div class='slide' style='width:" + slideSize.width + "px; height:" + slideSize.height + "px;" + bgColor + "'>";
@@ -330,7 +331,7 @@ namespace HiTeachCC.Service.PowerPoint.Implement
                     }
                     break;
                 case "p:graphicFrame":    // Chart, Diagram, Table
-                    ProcessGraphicFrameNode(items, node, order, warpObj);
+                    await  ProcessGraphicFrameNode(items, node, order, warpObj);
                     break;
                 case "p:grpSp":
                     await ProcessGroupSpNode(items, node, order, warpObj);
@@ -382,16 +383,17 @@ namespace HiTeachCC.Service.PowerPoint.Implement
             //return result;
         }
 
-        public string ProcessGraphicFrameNode(List<Item> items, XmlNode node, int order, WarpObj warpObj)
+        public async Task<string> ProcessGraphicFrameNode(List<Item> items, XmlNode node, int order, WarpObj warpObj)
         {
             var result = "";
-            var graphicTypeUri = node.GetTextByPath("a:graphic/a:graphicData/uri");
+            var graphicTypeUri = node.GetTextByPath("a:graphic/a:graphicData/@uri");
             if (graphicTypeUri != null)
             {
                 switch (graphicTypeUri.Value)
                 {
                     case "http://schemas.openxmlformats.org/drawingml/2006/table":
-                        result = GenTable(node, warpObj);
+                        Table table=  await GenTable(node,   order, warpObj);
+                        items.Add(table);
                         break;
                     case "http://schemas.openxmlformats.org/drawingml/2006/chart":
                         result = GenChart(node, warpObj);
@@ -416,11 +418,301 @@ namespace HiTeachCC.Service.PowerPoint.Implement
             return "";
         }
 
-        public string GenTable(XmlNode node, WarpObj warpObj)
+        public async Task<Table> GenTable(XmlNode node, int order, WarpObj warpObj)
         {
-            return "";
-        }
+            Table table = new Table();
+            var slideXfrmNode=   node.GetTextByPath("p:xfrm");
+            Position position = ShapeHelper.GetPosition(slideXfrmNode, null, null);
+            var tableNode = node.GetTextByPath("a:graphic/a:graphicData/a:tbl");
+            var getTblPr = tableNode.GetTextByPath("a:tblPr");
+            var getColsGrid = tableNode.GetTextByPath("a:tblGrid/a:gridCol");
+            var tblDir = "ltr";
+            XmlNode firstRowAttr = null  , bandRowAttr =null ;
+            if (getTblPr != null) {
+                var isRTL = getTblPr.GetTextByPath("@rtl");
+                tblDir = isRTL!=null && isRTL.Value.Equals("1") ? "rtl" : "ltr";
+                firstRowAttr = getTblPr.GetTextByPath("@firstRow"); //associated element <a:firstRow> in the table styles
+                var firstColAttr = getTblPr.GetTextByPath("@firstCol"); //associated element <a:firstCol> in the table styles
+                var lastRowAttr = getTblPr.GetTextByPath("@lastRow");//associated element <a:lastRow> in the table styles
+                var lastColAttr = getTblPr.GetTextByPath("@lastCol"); //associated element <a:lastCol> in the table styles
+                bandRowAttr = getTblPr.GetTextByPath("@bandRow"); //associated element <a:band1H>, <a:band2H> in the table styles
+                var bandColAttr = getTblPr.GetTextByPath("@bandCol"); //associated element <a:band1V>, <a:band2V> in the table styles
+            }
+            table.Dir = tblDir;
+            table.Position = position;
+            table.Type = "Table";
+            var trNodes = tableNode.GetTextByPathList("a:tr");
+
+            if (trNodes != null) {
+                int trSize = trNodes.Count;
+
+                for (int i = 0; i < trSize; i++)
+                {
+                    Tr tr = new Tr();
+                    var rowHeightParam = trNodes.Item(i).GetTextByPath("@h");
+                    double rowHeight = 0;
+                    //var rowsStyl = "";
+                    if (rowHeightParam != null) {
+                        rowHeight = int.Parse(rowHeightParam.Value) * px96 / px914400;
+                    }
+                    tr.height = rowHeight;
+                    XmlNode thisTblStyle=null;
+                    var tbleStyleId = getTblPr.GetTextByPath("a:tableStyleId");
+                    if (tbleStyleId != null)
+                    {
+                        var tbleStylList = warpObj.tableStyles.GetTextByPathList("a:tblStyleLst/a:tblStyle");
+                        foreach (XmlNode tbleStyle in tbleStylList)
+                        {
+                            if (tbleStyle.GetTextByPath("@styleId").Value.Equals(tbleStyleId.Value))
+                            {
+                                thisTblStyle = tbleStyle;
+                            }
+                        }
+                    }
+                    if (i == 0 && firstRowAttr != null && thisTblStyle != null)
+                    {
+                        var fillColor = "fff";
+                       // var colorOpacity = 1;
+                        if (thisTblStyle.GetTextByPath("a:firstRow") != null)
+                        {
+                            //处理纯色填充
+                            var bgFillschemeClr = thisTblStyle.GetTextByPath("a:firstRow/a:tcStyle/a:fill/a:solidFill");
+                            if (bgFillschemeClr != null)
+                            {
+                                fillColor = ShapeHelper.GetSolidFill(bgFillschemeClr, slideLayoutClrOvride, warpObj.slideMasterContent, warpObj.themeContent);
+                                fillColor = PowerPointHelper.ColorToning(bgFillschemeClr.OuterXml, fillColor);
+                                Fill f = new Fill { Color = fillColor, Type = 1 };
+                                tr.Fill = f;
+                            }
+                            //其他填充 todo
+                            var fill = thisTblStyle.GetTextByPath("a:firstRow/a:tcStyle/a:fill");
+                            string fillType = ShapeHelper.GetFillType(fill);
+                            var borderStyl = thisTblStyle.GetTextByPath("a:firstRow/a:tcStyle/a:tcBdr");
+                            if (borderStyl != null)
+                            {
+                                List<Border> borders = GetTableBorders(borderStyl, warpObj);
+                                tr.Borders = borders;
+                            }
+                            //Text Style - TODO
+                            //var rowTxtStyl = getTextByPathList(thisTblStyle,["a:firstRow", "a:tcTxStyle"]);
+                            //if (rowTxtStyl !== undefined)
+                            //{
+                            /*
+                        var fontClrPr = getFontColorPr(node, spNode, type, slideMasterTextStyles);
+                        var styleText = 
+                            "color:" + fontClrPr[0] + ";" +
+                            "text-shadow:" + fontClrPr[1] + ";" +
+                            "font-size:" + getFontSize(node, slideLayoutSpNode, slideMasterSpNode, type, slideMasterTextStyles) + ";" + 
+                            "font-family:" + getFontType(node, type, slideMasterTextStyles) + ";" + 
+                            "font-weight:" + getFontBold(node, type, slideMasterTextStyles) + ";" +
+                            "font-style:" + getFontItalic(node, type, slideMasterTextStyles) + ";" +
+                            "text-decoration:" + getFontDecoration(node, type, slideMasterTextStyles) + ";" +
+                            "text-align:" + getTextHorizontalAlign(node, type, slideMasterTextStyles) + ";" +
+                            "vertical-align:" + getTextVerticalAlign(node, type, slideMasterTextStyles) + ";";
+                            */
+                            //}
+                        }
+                    }
+                    else if (i > 0 && bandRowAttr != null && thisTblStyle != null)
+                    {
+                        var fillColor = "fff";
+                        // var colorOpacity = 1;
+                        if ((i % 2) == 0)
+                        {
+                            if (thisTblStyle.GetTextByPath("a:band2H") != null)
+                            {
+                                //处理纯色填充
+                                var bgFillschemeClr = thisTblStyle.GetTextByPath("a:band2H/a:tcStyle/a:fill/a:solidFill");
+                                if (bgFillschemeClr != null)
+                                {
+                                    fillColor = ShapeHelper.GetSolidFill(bgFillschemeClr, slideLayoutClrOvride, warpObj.slideMasterContent, warpObj.themeContent);
+                                    fillColor = PowerPointHelper.ColorToning(bgFillschemeClr.OuterXml, fillColor);
+                                    Fill f = new Fill { Color = fillColor, Type = 1 };
+                                    tr.Fill = f;
+                                }
+                                //其他填充 todo 
+                                var fill = thisTblStyle.GetTextByPath("a:band2H/a:tcStyle/a:fill");
+                                string fillType = ShapeHelper.GetFillType(fill);
+                                var borderStyl = thisTblStyle.GetTextByPath("a:band2H/a:tcStyle/a:tcBdr");
+                                if (borderStyl != null)
+                                {
+                                    List<Border> borders = GetTableBorders(borderStyl, warpObj);
+                                    tr.Borders = borders;
+                                }
+                                //Text Style - TODO
+                                //var rowTxtStyl = getTextByPathList(thisTblStyle,["a:band2H", "a:tcTxStyle"]);
+                                //if (rowTxtStyl !== undefined)
+                                //{
 
+                                //}
+                            }
+                            else
+                            {
+                                //处理纯色填充
+                                var bgFillschemeClr = thisTblStyle.GetTextByPath("a:wholeTbl/a:tcStyle/a:fill/a:solidFill");
+                                if (bgFillschemeClr != null)
+                                {
+                                    fillColor = ShapeHelper.GetSolidFill(bgFillschemeClr, slideLayoutClrOvride, warpObj.slideMasterContent, warpObj.themeContent);
+                                    fillColor = PowerPointHelper.ColorToning(bgFillschemeClr.OuterXml, fillColor);
+                                    Fill f = new Fill { Color = fillColor, Type = 1 };
+                                    tr.Fill = f;
+                                }
+                                //其他填充 todo 
+                                var fill = thisTblStyle.GetTextByPath("a:wholeTbl/a:tcStyle/a:fill");
+                                string fillType = ShapeHelper.GetFillType(fill);
+                                var borderStyl = thisTblStyle.GetTextByPath("a:wholeTbl/a:tcStyle/a:tcBdr");
+                                if (borderStyl != null)
+                                {
+                                    List<Border> borders = GetTableBorders(borderStyl, warpObj);
+                                    tr.Borders = borders;
+                                }
+                                //Text Style - TODO
+                                //var rowTxtStyl = thisTblStyle["a:wholeTbl"]["a:tcTxStyle"];
+                                //if (rowTxtStyl !== undefined)
+                                //{
+                                //}
+                            }
+                        }
+                        else {
+                            if (thisTblStyle.GetTextByPath("a:band1H") != null)
+                            {
+                                //处理纯色填充
+                                var bgFillschemeClr = thisTblStyle.GetTextByPath("a:band1H/a:tcStyle/a:fill/a:solidFill");
+                                if (bgFillschemeClr != null)
+                                {
+                                    fillColor = ShapeHelper.GetSolidFill(bgFillschemeClr, slideLayoutClrOvride, warpObj.slideMasterContent, warpObj.themeContent);
+                                    fillColor = PowerPointHelper.ColorToning(bgFillschemeClr.OuterXml, fillColor);
+                                    Fill f = new Fill { Color = fillColor, Type = 1 };
+                                    tr.Fill = f;
+                                }
+                                //其他填充 todo 
+                                var fill = thisTblStyle.GetTextByPath("a:band1H/a:tcStyle/a:fill");
+                                string fillType = ShapeHelper.GetFillType(fill);
+                                var borderStyl = thisTblStyle.GetTextByPath("a:band1H/a:tcStyle/a:tcBdr");
+                                if (borderStyl != null)
+                                {
+                                    List<Border> borders = GetTableBorders(borderStyl, warpObj);
+                                    tr.Borders = borders;
+                                }
+                                //Text Style - TODO
+                                //var rowTxtStyl = getTextByPathList(thisTblStyle,["a:band1H", "a:tcTxStyle"]);
+                                //if (rowTxtStyl !== undefined)
+                                //{
+
+                                //}
+                            }
+                        }
+                    }
+                    var tcNodes= trNodes.Item(i).GetTextByPathList("a:tc");
+                    if (tcNodes != null) {
+                        int tcSize = tcNodes.Count;
+                        for (int j = 0; j < tcSize; j++) {
+                            Td td = new Td();
+                            List<Paragraph> paragraphs=   await GenTextBody(tcNodes.Item(j).GetTextByPath("a:txBody"),node,null,null,null,warpObj);
+                            var rowSpan = tcNodes.Item(j).GetTextByPath( "@rowSpan");
+                            var colSpan = tcNodes.Item(j).GetTextByPath("@gridSpan");
+                            var vMerge = tcNodes.Item(j).GetTextByPath("@vMerge");
+                            var hMerge = tcNodes.Item(j).GetTextByPath("@hMerge");
+                            var colWidthParam = getColsGrid.GetTextByPath("@w");
+                            if (colWidthParam != null) {
+                                td.width = int.Parse(colWidthParam.Value) * px96 / px914400;
+                            }
+                            var getFill = tcNodes.Item(j).GetTextByPath("a:tcPr/a:solidFill");
+                            string fillColor = "";
+                            if (getFill != null)
+                            {
+                                fillColor = ShapeHelper.GetSolidFill(getFill, slideLayoutClrOvride, warpObj.slideMasterContent, warpObj.themeContent);
+                                fillColor = PowerPointHelper.ColorToning(getFill.OuterXml, fillColor);
+                                Fill f = new Fill { Color = fillColor, Type = 1 };
+                                td.Fill = f;
+                            }
+                            else {
+                                //get from Theme (tableStyles.xml) TODO 
+                                //get tableStyleId = a:tbl => a:tblPr => a:tableStyleId
+                                //var tbleStyleId = getTblPr["a:tableStyleId"];
+                                //if (tbleStyleId !== undefined)
+                                //{
+                                //    //get Style from tableStyles.xml by {var tbleStyleId}
+                                //    //table style object : tableStyles
+                                //    var tbleStylList = tableStyles["a:tblStyleLst"]["a:tblStyle"];
+
+                                //    for (var k = 0; k < tbleStylList.length; k++)
+                                //    {
+                                //        if (tbleStylList[k]["attrs"]["styleId"] == tbleStyleId)
+                                //        {
+                                //            //console.log(tbleStylList[k]);
+                                //        }
+                                //    }
+                                //}
+                            }
+                            //其他填充 todo 
+                            if (rowSpan != null) {
+                                td.Rowspan = int.Parse(rowSpan.Value);
+                            }
+                            if (colSpan != null)
+                            {
+                                td.Colspan = int.Parse(colSpan.Value);
+                            }
+                            //
+                            if (vMerge != null)
+                            {
+                                td.VMerge = int.Parse(vMerge.Value);
+                            }
+                            if (colSpan != null)
+                            {
+                                td.HMerge = int.Parse(colSpan.Value);
+                            }
+                            if (rowSpan == null && colSpan == null && vMerge == null && hMerge == null) {
+                                td.Rowspan = 0;
+                                td.Colspan = 0;
+                                td.HMerge = 0;
+                                td.VMerge = 0;
+                            }
+                            td.Paragraphs = paragraphs;
+                            tr.Td.Add(td);
+                        }
+                    }
+                    table.Tr.Add(tr);
+                }
+            }
+            return table;
+        }
+       private List<Border> GetTableBorders(XmlNode node, WarpObj warpObj) {
+            List<Border> borders = new List<Border>();
+            if (node.GetTextByPath("a:bottom") != null) {
+                string xml= "<p:spPr><a:ln>"+  node.GetTextByPath("a:bottom/a:ln").InnerXml + "</p:spPr></a:ln>";
+                XmlDocument nodeDoc = new XmlDocument();
+                nodeDoc.LoadXml(xml);
+                Border border=  ShapeHelper.GetBorder(nodeDoc, false, "shape", slideLayoutClrOvride, warpObj.slideMasterContent, warpObj.themeContent);
+                border.Dir = "bottom";
+                borders.Add(border);
+            }
+            if (node.GetTextByPath("a:top") != null)
+            {
+                string xml = "<p:spPr><a:ln>" + node.GetTextByPath("a:top/a:ln").InnerXml + "</p:spPr></a:ln>";
+                XmlDocument nodeDoc = new XmlDocument();
+                nodeDoc.LoadXml(xml);
+                Border border = ShapeHelper.GetBorder(nodeDoc, false, "shape", slideLayoutClrOvride, warpObj.slideMasterContent, warpObj.themeContent);
+                border.Dir = "top"; borders.Add(border);
+            }
+            if (node.GetTextByPath("a:right") != null)
+            {
+                string xml = "<p:spPr><a:ln>" + node.GetTextByPath("a:right/a:ln").InnerXml + "</p:spPr></a:ln>";
+                XmlDocument nodeDoc = new XmlDocument();
+                nodeDoc.LoadXml(xml);
+                Border border = ShapeHelper.GetBorder(nodeDoc, false, "shape", slideLayoutClrOvride, warpObj.slideMasterContent, warpObj.themeContent);
+                border.Dir = "right"; borders.Add(border);
+            }
+            if (node.GetTextByPath("a:left") != null)
+            {
+                string xml = "<p:spPr><a:ln>" + node.GetTextByPath("a:left/a:ln").InnerXml + "</p:spPr></a:ln>";
+                XmlDocument nodeDoc = new XmlDocument();
+                nodeDoc.LoadXml(xml);
+                Border border = ShapeHelper.GetBorder(nodeDoc, false, "shape", slideLayoutClrOvride, warpObj.slideMasterContent, warpObj.themeContent);
+                border.Dir = "left"; borders.Add(border);
+            }
+            return borders;
+        }
 
         public async Task<Item> ProcessCxnSpNode(XmlNode node, int order, WarpObj warpObj)
         {

+ 5 - 4
TEAMModelOS.Service/Services/PowerPoint/Implement/ShapeHelper.cs

@@ -12,6 +12,7 @@ namespace TEAMModelOS.Service.Services.PowerPoint.Implement
 {
     public static class ShapeHelper
     {
+        private const int degree = 3;
         private const double px96 = 96.00, px72 = 72.00, px914400 = 914400.00, px12700 = 12700.00;
         private const double rot60000 = 60000.00;
         public static Border GetBorder(XmlNode node, bool isSvgMode, string bType, Dictionary<string, string> slideLayoutClrOvride, XmlNode slideMasterContent ,  XmlNode themeContent)
@@ -540,10 +541,10 @@ namespace TEAMModelOS.Service.Services.PowerPoint.Implement
             {
                 off = PowerPointHelper.GetTextByPath(slideMasterXfrmNode, "a:off");
             }
-            x =System.Math.Round(double.Parse(off.GetTextByPath("@x").Value) * px96 / px914400,3);
-            y =   System.Math.Round(double.Parse(off.GetTextByPath("@y").Value) * px96 / px914400,3);
-            w =   System.Math.Round(double.Parse(ext.GetTextByPath("@cx").Value) * px96 / px914400,3);
-            h = System.Math.Round(double.Parse(ext.GetTextByPath("@cy").Value) * px96 / px914400,3);
+            x = System.Math.Round(double.Parse(off.GetTextByPath("@x").Value) * px96 / px914400, degree);
+            y = System.Math.Round(double.Parse(off.GetTextByPath("@y").Value) * px96 / px914400, degree);
+            w = System.Math.Round(double.Parse(ext.GetTextByPath("@cx").Value) * px96 / px914400, degree);
+            h = System.Math.Round(double.Parse(ext.GetTextByPath("@cy").Value) * px96 / px914400, degree);
             return new Position()
             {
                 Cx = w,