using TEAMModelOS.Service.Model.PowerPoint;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Xml;
using TEAMModelOS.SDK.Helper.Common.ColorHelper;
using TEAMModelOS.Service.Models.PowerPoint.Inner;
namespace TEAMModelOS.Service.Services.PowerPoint.Implement
{
public static class ShapeHelper
{
private const int degree = 4;
private const double px96 = 96.00, px72 = 72.00, px914400 = 914400.00, px12700 = 12700.00;
private const double rot60000 = 60000.00;
public static XmlNamespaceManager xmlnsManager;
public static XmlNode GetTextByPath(this XmlDocument document, string expression)
{
return document.SelectSingleNode(expression, xmlnsManager);
}
public static XmlNode GetTextByPath(this XmlNode node, string expression)
{
return node.SelectSingleNode(expression, xmlnsManager);
}
public static XmlNodeList GetTextByPathList(this XmlDocument document, string expression)
{
return document.SelectNodes(expression, xmlnsManager);
}
public static XmlNodeList GetTextByPathList(this XmlNode node, string expression)
{
return node.SelectNodes(expression, xmlnsManager);
}
static ShapeHelper()
{
xmlnsManager = new XmlNamespaceManager(new NameTable());
xmlnsManager.AddNamespace("p", "http://schemas.openxmlformats.org/presentationml/2006/main");
xmlnsManager.AddNamespace("a", "http://schemas.openxmlformats.org/drawingml/2006/main");
xmlnsManager.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");
xmlnsManager.AddNamespace("fo", "http://www.w3.org/1999/XSL/Format");
xmlnsManager.AddNamespace("app", "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties");
xmlnsManager.AddNamespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
xmlnsManager.AddNamespace("dc", "http://purl.org/dc/elements/1.1/");
xmlnsManager.AddNamespace("dcterms", "http://purl.org/dc/terms/");
xmlnsManager.AddNamespace("dcmitype", "http://purl.org/dc/dcmitype/");
xmlnsManager.AddNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships");
xmlnsManager.AddNamespace("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
xmlnsManager.AddNamespace("cus", "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties");
xmlnsManager.AddNamespace("vt", "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes");
xmlnsManager.AddNamespace("pic", "http://schemas.openxmlformats.org/drawingml/2006/picture");
xmlnsManager.AddNamespace("dsp", "http://schemas.microsoft.com/office/drawing/2008/diagram");
xmlnsManager.AddNamespace("dgm", "http://schemas.openxmlformats.org/drawingml/2006/diagram");
xmlnsManager.AddNamespace("a14", "http://schemas.microsoft.com/office/drawing/2010/main");
xmlnsManager.AddNamespace("m", "http://schemas.openxmlformats.org/officeDocument/2006/math");
xmlnsManager.AddNamespace("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
xmlnsManager.AddNamespace("p14", "http://schemas.microsoft.com/office/powerpoint/2010/main");
xmlnsManager.AddNamespace("pkg", "http://schemas.microsoft.com/office/2006/xmlPackage");
xmlnsManager.AddNamespace("p15", "http://schemas.microsoft.com/office/powerpoint/2012/main");
xmlnsManager.AddNamespace("a16", "http://schemas.microsoft.com/office/drawing/2014/main");
xmlnsManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
xmlnsManager.AddNamespace("c", "http://schemas.openxmlformats.org/drawingml/2006/chart");
xmlnsManager.AddNamespace("c14", "http://schemas.microsoft.com/office/drawing/2007/8/2/chart");
xmlnsManager.AddNamespace("c16", "http://schemas.microsoft.com/office/drawing/2014/chart");
xmlnsManager.AddNamespace("cs", "http://schemas.microsoft.com/office/drawing/2012/chartStyle");
xmlnsManager.AddNamespace("thm15", "http://schemas.microsoft.com/office/thememl/2012/main");
xmlnsManager.AddNamespace("fn", "http://www.w3.org/2005/xpath-functions");
}
///
/// 调色补充 Shade Tint LumMod LumOff 等
///
///
///
///
public static string ColorToning(string nodeXml, string colorHex)
{
if (string.IsNullOrEmpty(colorHex)) { return null; }
TEAMModelOS.SDK.Helper.Common.ColorHelper.ColorConverter converter = new TEAMModelOS.SDK.Helper.Common.ColorHelper.ColorConverter();
XmlDocument doc = new XmlDocument();
doc.LoadXml(nodeXml);
XmlNode tint = doc.SelectSingleNode("//a:tint/@val", xmlnsManager);
if (tint != null)
{
colorHex = converter.SetTint(colorHex, double.Parse(tint.Value));
}
XmlNode hueMod = doc.SelectSingleNode("//a:hueMod/@val", xmlnsManager);
if (hueMod != null)
{
colorHex = converter.SetHueMod(colorHex, double.Parse(hueMod.Value));
}
XmlNode satMod = doc.SelectSingleNode("//a:satMod/@val", xmlnsManager);
if (satMod != null)
{
colorHex = converter.SetSaturationMod(colorHex, double.Parse(satMod.Value));
}
XmlNode satOff = doc.SelectSingleNode("//a:satOff/@val", xmlnsManager);
if (satOff != null)
{
colorHex = converter.SetSaturationOff(colorHex, double.Parse(satOff.Value));
}
XmlNode lumMod = doc.SelectSingleNode("//a:lumMod/@val", xmlnsManager);
if (lumMod != null)
{
colorHex = converter.SetLuminanceMod(colorHex, double.Parse(lumMod.Value));
}
XmlNode lumOff = doc.SelectSingleNode("//a:lumOff/@val", xmlnsManager);
if (lumOff != null)
{
colorHex = converter.SetLuminanceOff(colorHex, double.Parse(lumOff.Value));
}
XmlNode hueOff = doc.SelectSingleNode("//a:hueOff/@val", xmlnsManager);
if (hueOff != null)
{
colorHex = converter.SetHueOff(colorHex, double.Parse(hueOff.Value));
}
XmlNode alphaOff = doc.SelectSingleNode("//a:alphaOff/@val", xmlnsManager);
if (alphaOff != null)
{
// Color color= ColorTranslator.FromHtml("#" + colorHex);
// color = Color.FromArgb(byte.Parse(int.Parse(alpha.Value)/100000+""),color.R,color.G,color.B);
}
XmlNode shade = doc.SelectSingleNode("//a:shade/@val", xmlnsManager);
if (shade != null)
{
colorHex = converter.SetShade(colorHex, double.Parse(shade.Value));
}
XmlNode alpha = doc.SelectSingleNode("//a:alpha/@val", xmlnsManager);
if (alpha != null)
{
// Color color= ColorTranslator.FromHtml("#" + colorHex);
// color = Color.FromArgb(byte.Parse(int.Parse(alpha.Value)/100000+""),color.R,color.G,color.B);
}
return colorHex;
}
public static Border GetBorder(XmlNode node, bool isSvgMode, string bType, Dictionary 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 slideLayoutClrOvride, XmlNode themeContent)
{
// in slide master
// e.g. tx2="dk2" bg2="lt2" tx1="dk1" bg1="lt1" slideLayoutClrOvride
if (slideLayoutClrOvride == null || slideLayoutClrOvride.Count <= 0)
{
if (sldMasterNode != null)
{
var sldLayoutClrOvr = ShapeHelper.GetTextByPath(sldMasterNode, "p:sldMaster/p:clrMap");
if (sldLayoutClrOvr != null)
{
//获取 overrideClrMapping所有属性节点 检查测试 是否slideLayoutClrOvride 需要被覆盖
slideLayoutClrOvride = new Dictionary() {
{ "accent1", sldLayoutClrOvr.GetTextByPath("@accent1").Value},
{ "accent2", sldLayoutClrOvr.GetTextByPath("@accent2").Value},
{ "accent3", sldLayoutClrOvr.GetTextByPath("@accent3").Value},
{ "accent4", sldLayoutClrOvr.GetTextByPath("@accent4").Value},
{ "accent5", sldLayoutClrOvr.GetTextByPath("@accent5").Value},
{ "accent6", sldLayoutClrOvr.GetTextByPath("@accent6").Value},
{ "bg1", sldLayoutClrOvr.GetTextByPath("@bg1").Value},
{ "bg2", sldLayoutClrOvr.GetTextByPath("@bg2").Value},
{ "folHlink", sldLayoutClrOvr.GetTextByPath("@folHlink").Value},
{ "hlink", sldLayoutClrOvr.GetTextByPath("@hlink").Value},
{ "tx1", sldLayoutClrOvr.GetTextByPath("@tx1").Value},
{ "tx2", sldLayoutClrOvr.GetTextByPath("@tx2").Value}
};
}
}
}
if (!schemeClr.StartsWith("a:"))
{
schemeClr = "a:" + schemeClr;
}
//console.log(slideLayoutClrOvride);
var schmClrName = schemeClr.Replace("a:", "");
if (slideLayoutClrOvride != null)
{
switch (schmClrName)
{
case "tx1":
case "tx2":
case "bg1":
case "bg2":
schemeClr = "a:" + slideLayoutClrOvride[schmClrName];
//schemeClr = "a:" + slideLayoutClrOvride[schmClrName];
//console.log(schmClrName+ "=> "+schemeClr);
break;
}
}
else
{
switch (schmClrName)
{
case "tx1":
schemeClr = "a:dk1";
break;
case "tx2":
schemeClr = "a:dk2";
break;
case "bg1":
schemeClr = "a:lt1";
break;
case "bg2":
schemeClr = "a:lt2";
break;
}
}
//var refNode = ShapeHelper.GetTextByPathList(themeContent, "a:theme/a:themeElements/a:clrScheme/"+ schemeClr.Value);
var color = ShapeHelper.GetTextByPath(themeContent, "pkg:xmlData/a:theme/a:themeElements/a:clrScheme/" + schemeClr + "/a:srgbClr/@val");
if (color == null)//&& refNode != null
{
color = ShapeHelper.GetTextByPath(themeContent, "pkg:xmlData/a:theme/a:themeElements/a:clrScheme/" + schemeClr + "/a:sysClr/@lastClr");
}
//console.log(color)
return color.Value;
}
public static string GetSvgImagePattern(string fillColor, int shpId)
{
var ptrn = "";// '';
ptrn += "";// '';
ptrn += "";// '';
return ptrn;
}
public static string GetSvgGradient(double w, double h, double angl, List color_arry, int shpId, Dictionary slideLayoutClrOvride, XmlNode themeContent)
{
var stopsArray = GetMiddleStops(color_arry.Count - 2);
var svgAngle = "";
double svgHeight = h;
double svgWidth = w;
string svg = "";
List xy_ary = SVGangle(angl, svgHeight, svgWidth, slideLayoutClrOvride, themeContent);
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 = "\n";
svg += svgAngle;
for (var i = 0; i < sal; i++)
{
svg += "\n";
}
svg += "\n" + "";
return svg;
}
public static List GetMiddleStops(int s)
{
var sArry = new List { "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 static List SVGangle(double deg, double svgHeight, double svgWidth, Dictionary slideLayoutClrOvride, XmlNode themeContent)
{
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.0;
double y1 = System.Math.Round(ty2 / h * 100 * 100) / 100.0;
double x2 = System.Math.Round(tx1 / w * 100 * 100) / 100.0;
double y2 = System.Math.Round(ty1 / h * 100 * 100) / 100.0;
return new List { x1, y1, x2, y2 };
}
public static Fill GetPatternFill(XmlNode node, Dictionary slideLayoutClrOvride, XmlNode slideMasterContent, XmlNode themeContent)
{
Fill fill = new Fill { type = 4 };
//处理前景色
var fgClr = node.GetTextByPath("a:fgClr");
string fgclr = GetSolidFill(fgClr, slideLayoutClrOvride, slideMasterContent, themeContent);
if (fgClr != null) {
fgclr = ShapeHelper.ColorToning(fgClr.OuterXml, fgclr);
}
fill.grad.Add(fgclr);
// 处理背景色
var bgClr = node.GetTextByPath("a:bgClr");
string bgclr = GetSolidFill(bgClr, slideLayoutClrOvride, slideMasterContent, themeContent);
if (bgClr != null) {
bgclr = ShapeHelper.ColorToning(bgClr.OuterXml, bgclr);
}
//处理内置图案属性
var prst = node.GetTextByPath("@prst");
if (prst != null)
{
fill.patt = prst.Value;
}
fill.grad.Add(bgclr);
return fill;
}
public static dynamic GetSlideSize(XmlDocument xdoc)
{
var sldSzNode = xdoc.GetTextByPath("//pkg:part[@pkg:name='/ppt/presentation.xml']/pkg:xmlData/p:presentation/p:sldSz");
double width = double.Parse(sldSzNode.GetTextByPath("@cx").Value) * px96 / px914400;
double height = double.Parse(sldSzNode.GetTextByPath("@cy").Value) * px96 / px914400;
return new { width, height };
}
public static Fill GetGradientFill(XmlNode node, Dictionary slideLayoutClrOvride, XmlNode slideMasterContent, XmlNode themeContent)
{
XmlNodeList gsLst = ShapeHelper.GetTextByPathList(node, "a:gsLst/a:gs");// node["a:gsLst"]["a:gs"];
//get start color
var color_ary = new List();
for (int i = 0; i < gsLst.Count; i++)
{
var lo_color = GetSolidFill(gsLst[i], slideLayoutClrOvride, slideMasterContent, themeContent);
lo_color = ShapeHelper.ColorToning(gsLst[i].OuterXml, lo_color);
color_ary.Add(lo_color);
}
//get rot
var lin = ShapeHelper.GetTextByPathList(node, "a:lin");// node["a:lin"];
double rot = 0;
if (lin != null)
{
rot = AngleToDegrees(ShapeHelper.GetTextByPath(node, "a:lin/@ang")) + 90;
}
return new Fill()
{
type = 2,
grad = color_ary,
rot = rot
};
}
public static Position GetPosition(XmlNode slideXfrmNode, XmlNode slideLayoutXfrmNode, XmlNode slideMasterXfrmNode)
{
XmlNode off = null;
XmlNode ext = null;
double x, y, w, h;
//ext
if (slideXfrmNode != null)
{
ext = ShapeHelper.GetTextByPath(slideXfrmNode, "a:ext");
}
else if (slideLayoutXfrmNode != null && ext == null)
{
ext = ShapeHelper.GetTextByPath(slideLayoutXfrmNode, "a:ext");
}
else if (slideMasterXfrmNode != null && ext == null)
{
ext = ShapeHelper.GetTextByPath(slideMasterXfrmNode, "a:ext");
}
//off
if (slideXfrmNode != null)
{
off = ShapeHelper.GetTextByPath(slideXfrmNode, "a:off");
}
else if (slideLayoutXfrmNode != null && off == null)
{
off = ShapeHelper.GetTextByPath(slideLayoutXfrmNode, "a:off");
}
else if (slideMasterXfrmNode != null && off == null)
{
off = ShapeHelper.GetTextByPath(slideMasterXfrmNode, "a:off");
}
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,
cy = h,
x = x,
y = y
};
}
public static NodesTable IndexNodes(XmlNode content)
{
var idTable = new Dictionary();
var idxTable = new Dictionary();
var typeTable = new Dictionary();
var spTreeNode = content.GetTextByPath("p:cSld/p:spTree");
// Dictionary> slideResObj = new Dictionary>();
var spTreeNodeChildren = spTreeNode.ChildNodes;
foreach (XmlNode child in spTreeNodeChildren)
{
if (child.Name.Equals("p:nvGrpSpPr") || child.Name.Equals("p:grpSpPr"))
{
continue;
}
//var targetNode = child.ChildNodes;
var targetNode = child.GetTextByPath("p:nvSpPr");
// < p:cNvCxnSpPr >
// < a:cxnSpLocks /> ///这个是什么意思
// p:cNvCxnSpPr >
if (targetNode == null)
{
targetNode = child.GetTextByPath("p:nvCxnSpPr");
}
XmlNode id = null, idx = null, type = null;
if (targetNode != null) {
id = targetNode.GetTextByPath("p:cNvPr/@id");
idx = targetNode.GetTextByPath("p:nvPr/p:ph/@idx");
type = targetNode.GetTextByPath("p:nvPr/p:ph/@type");
}
// Dictionary node = new Dictionary();
//if (child.ChildNodes != null)
//{
// foreach (XmlNode xmlNode in child.ChildNodes)
// {
// node.TryAdd(xmlNode.Name, xmlNode);
// }
//}
if (id != null)
{
idTable[id.Value] = child;
}
if (idx != null)
{
idxTable[idx.Value] = child;
}
if (type != null)
{
//会出现相同Key
typeTable[type.Value] = child;
}
}
return new NodesTable { idTable = idTable, idxTable = idxTable, typeTable = typeTable };
}
public static double AngleToDegrees(XmlNode angle)
{
if (angle == null)
{
return 0;
}
return double.Parse(angle.Value) / rot60000;
}
public static XmlNode GetNodesTable(XmlNode id, XmlNode idx, XmlNode type, WarpObj warpObj, string LayoutOrMaster)
{
XmlNode resNode = null;
if (resNode == null)
{
if (id != null)
{
if (LayoutOrMaster.Equals("Layout"))
{
if (warpObj.slideLayoutTables.idTable.TryGetValue(id.Value, out XmlNode LayoutNode))
{
// LayoutNode.TryGetValue(id.Value, out XmlNode node);
resNode = LayoutNode;
};
}
if (LayoutOrMaster.Equals("Master"))
{
if (warpObj.slideMasterTables.idTable.TryGetValue(id.Value, out XmlNode MasterNode))
{
// LayoutNode.TryGetValue(id.Value, out XmlNode node);
resNode = MasterNode;
};
}
}
}
if (resNode == null)
{
if (idx != null)
{
if (LayoutOrMaster.Equals("Layout"))
{
if (warpObj.slideLayoutTables.idxTable.TryGetValue(idx.Value, out XmlNode LayoutNode))
{
//LayoutNode.TryGetValue(idx.Value, out XmlNode node);
resNode = LayoutNode;
};
}
if (LayoutOrMaster.Equals("Master"))
{
if (warpObj.slideMasterTables.idxTable.TryGetValue(idx.Value, out XmlNode MasterNode))
{
// LayoutNode.TryGetValue(idx.Value, out XmlNode node);
resNode = MasterNode;
};
}
}
}
if (resNode == null)
{
if (type != null)
{
if (LayoutOrMaster.Equals("Layout"))
{
if (warpObj.slideLayoutTables.typeTable.TryGetValue(type.Value, out XmlNode LayoutNode))
{
// LayoutNode.TryGetValue(type.Value, out XmlNode node);
resNode = LayoutNode;
};
}
if (LayoutOrMaster.Equals("Master"))
{
if (warpObj.slideMasterTables.typeTable.TryGetValue(type.Value, out XmlNode MasterNode))
{
// MasterNode.TryGetValue(type.Value, out XmlNode node);
resNode = MasterNode;
};
}
}
}
return resNode;
}
public static string HexToRgbNew(string bgColor)
{
//var arrBuff = new ArrayBuffer(4);
//var vw = new DataView(arrBuff);
//vw.setUint32(0, parseInt(hex, 16), false);
//var arrByte = new Uint8Array(arrBuff);
int r = Convert.ToInt32("0x" + bgColor.Substring(0, 2), 16);
int g = Convert.ToInt32("0x" + bgColor.Substring(2, 2), 16);
int b = Convert.ToInt32("0x" + bgColor.Substring(4, 2), 16);
return r + "," + g + "," + b;
}
public static double GetColorOpacity(XmlNode solidFill)
{
double opcity = 1;
if (solidFill == null)
{
return opcity;
}
if (solidFill.GetTextByPath("a:srgbClr") != null)
{
var tint = solidFill.GetTextByPath("a:srgbClr/a:tint/@val");
if (tint != null)
{
opcity = double.Parse(tint.Value) / 100000.0;
}
}
else if (solidFill.GetTextByPath("a:schemeClr") != null)
{
var tint = solidFill.GetTextByPath("a:schemeClr/a:tint/@val");
if (tint != null)
{
opcity = double.Parse(tint.Value) / 100000.0;
}
}
else if (solidFill.GetTextByPath("a:scrgbClr") != null)
{
var tint = solidFill.GetTextByPath("a:scrgbClr/a:tint/@val");
if (tint != null)
{
opcity = double.Parse(tint.Value) / 100000.0;
}
}
else if (solidFill.GetTextByPath("a:prstClr") != null)
{
var tint = solidFill.GetTextByPath("a:prstClr/a:tint/@val");
if (tint != null)
{
opcity = double.Parse(tint.Value) / 100000.0;
}
}
else if (solidFill.GetTextByPath("a:hslClr") != null)
{
var tint = solidFill.GetTextByPath("a:hslClr/a:tint/@val");
if (tint != null)
{
opcity = double.Parse(tint.Value) / 100000.0;
}
}
else if (solidFill.GetTextByPath("a:sysClr") != null)
{
var tint = solidFill.GetTextByPath("a:sysClr/a:tint/@val");
if (tint != null)
{
opcity = double.Parse(tint.Value) / 100000.0;
}
}
return opcity;
}
public static Fill GetBgGradientFill(XmlNode bgPr, string phClr, Dictionary slideLayoutClrOvride, XmlNode slideMasterContent, XmlNode themeContent)
{
if (bgPr != null)
{
var grdFill = bgPr.GetTextByPath("a:gradFill");
return GetGradientFill(grdFill, slideLayoutClrOvride, slideMasterContent, themeContent);
}
else
{
if (phClr == null)
{
return new Fill { type = 1, color = phClr };
}
}
return null;
}
public static string GetSolidFill(XmlNode node, Dictionary slideLayoutClrOvride, XmlNode slideMasterContent, XmlNode themeContent)
{
if (node == null)
{
return null;
}
string Color =null;
// Fill fill = new Fill() { Color = "FFF", Type = 1 };
var srgbClrval = node.GetTextByPath("a:srgbClr/@val");
var schemeClrval = node.GetTextByPath("a:schemeClr/@val");
if (srgbClrval != null)
{
Color = srgbClrval.Value; //#...
}
else if (schemeClrval != null)//node["a:schemeClr"] != null)
{
//a:schemeClr
// var schemeClr = ShapeHelper.GetTextByPath(node, "a:schemeClr/@val");
//console.log(schemeClr)
Color = ShapeHelper.GetSchemeColorFromTheme(schemeClrval.Value, slideMasterContent, slideLayoutClrOvride, themeContent); //#...
}
else if (ShapeHelper.GetTextByPath(node, "a:scrgbClr") != null)
{
// //Need to test/////////////////////////////////////////////
var defBultColorValsR = ShapeHelper.GetTextByPath(node, "a:scrgbClr/@r");
var defBultColorValsG = ShapeHelper.GetTextByPath(node, "a:scrgbClr/@g");
var defBultColorValsB = ShapeHelper.GetTextByPath(node, "a:scrgbClr/@b");
var red = (defBultColorValsR.Value.IndexOf("%") != -1) ? defBultColorValsR.Value.Split("%").First() : defBultColorValsR.Value;
var green = (defBultColorValsG.Value.IndexOf("%") != -1) ? defBultColorValsG.Value.Split("%").First() : defBultColorValsG.Value;
var blue = (defBultColorValsB.Value.IndexOf("%") != -1) ? defBultColorValsB.Value.Split("%").First() : defBultColorValsB.Value;
var scrgbClr = red + "," + green + "," + blue;
Color = ToHex(255 * (int.Parse(red) / 100)) + ToHex(255 * (int.Parse(green) / 100)) + ToHex(255 * (int.Parse(blue) / 100));
//console.log("scrgbClr: " + scrgbClr);
}
else if (ShapeHelper.GetTextByPath(node, "a:prstClr") != null)
{
// //Need to test/////////////////////////////////////////////
var prstClr = ShapeHelper.GetTextByPath(node, "a:prstClr/@val");// node["a:prstClr"]["attrs"]["val"];
Color = GetColorName2Hex(prstClr.Value);
//console.log("prstClr: " + prstClr+" => hexClr: "+color);
}
else if (ShapeHelper.GetTextByPath(node, "a:hslClr") != null)
{
// //Need to test/////////////////////////////////////////////
var defBultColorVals = ShapeHelper.GetTextByPath(node, "a:hslClr");//["attrs"];
var defBultColorVals_hue = ShapeHelper.GetTextByPath(defBultColorVals, "@hue");
var defBultColorVals_sat = ShapeHelper.GetTextByPath(defBultColorVals, "@sat");
var defBultColorVals_lum = ShapeHelper.GetTextByPath(defBultColorVals, "@lum");
var hue = int.Parse(defBultColorVals_hue.Value) / 100000;
var sat = int.Parse((defBultColorVals_sat.Value.IndexOf("%") != -1) ? defBultColorVals_sat.Value.Split("%").First() : defBultColorVals_sat.Value) / 100;
var lum = int.Parse((defBultColorVals_lum.Value.IndexOf("%") != -1) ? defBultColorVals_lum.Value.Split("%").First() : defBultColorVals_lum.Value) / 100;
var hslClr = defBultColorVals_hue.Value.ToString() + "," + defBultColorVals_sat.Value.ToString() + "," + defBultColorVals_lum.Value.ToString();
var hsl2rgb = HslToRgb(hue, sat, lum);
Color = ToHex(hsl2rgb.r) + ToHex(hsl2rgb.g) + ToHex(hsl2rgb.b);
//defBultColor = cnvrtHslColor2Hex(hslClr); //TODO
// console.log("hslClr: " + hslClr);
}
else if (ShapeHelper.GetTextByPath(node, "a:sysClr") != null)
{
// //Need to test/////////////////////////////////////////////
var sysClr = ShapeHelper.GetTextByPath(node, "a:sysClr/@lastClr").Value;
if (sysClr != null)
{
Color = sysClr;
}
}
return Color;
}
public static string ToHex(int n)
{
string hex= Convert.ToString(n, 16);
while (hex.Length < 2) { hex = "0" + hex; }
return hex;
}
public static dynamic HslToRgb(int hue, int sat, int light)
{
int t1, t2, r, g, b;
hue /= 60;
if (light <= 0.5)
{
t2 = light * (sat + 1);
}
else
{
t2 = light + sat - (light * sat);
}
t1 = light * 2 - t2;
r = HueToRgb(t1, t2, hue + 2) * 255;
g = HueToRgb(t1, t2, hue) * 255;
b = HueToRgb(t1, t2, hue - 2) * 255;
return new { r, g, b };
}
public static int HueToRgb(int t1, int t2, int hue)
{
if (hue < 0) hue += 6;
if (hue >= 6) hue -= 6;
if (hue < 1) return (t2 - t1) * hue + t1;
else if (hue < 3) return t2;
else if (hue < 4) return (t2 - t1) * (4 - hue) + t1;
else return t1;
}
public static string GetColorName2Hex(string name)
{
var hex = "";
var colorName = new List { "AntiqueWhite", "Aqua", "Aquamarine", "Azure", "Beige", "Bisque", "Black", "BlanchedAlmond", "Blue", "BlueViolet", "Brown", "BurlyWood", "CadetBlue", "Chartreuse", "Chocolate", "Coral", "CornflowerBlue", "Cornsilk", "Crimson", "Cyan", "DarkBlue", "DarkCyan", "DarkGoldenRod", "DarkGray", "DarkGrey", "DarkGreen", "DarkKhaki", "DarkMagenta", "DarkOliveGreen", "DarkOrange", "DarkOrchid", "DarkRed", "DarkSalmon", "DarkSeaGreen", "DarkSlateBlue", "DarkSlateGray", "DarkSlateGrey", "DarkTurquoise", "DarkViolet", "DeepPink", "DeepSkyBlue", "DimGray", "DimGrey", "DodgerBlue", "FireBrick", "FloralWhite", "ForestGreen", "Fuchsia", "Gainsboro", "GhostWhite", "Gold", "GoldenRod", "Gray", "Grey", "Green", "GreenYellow", "HoneyDew", "HotPink", "IndianRed", "Indigo", "Ivory", "Khaki", "Lavender", "LavenderBlush", "LawnGreen", "LemonChiffon", "LightBlue", "LightCoral", "LightCyan", "LightGoldenRodYellow", "LightGray", "LightGrey", "LightGreen", "LightPink", "LightSalmon", "LightSeaGreen", "LightSkyBlue", "LightSlateGray", "LightSlateGrey", "LightSteelBlue", "LightYellow", "Lime", "LimeGreen", "Linen", "Magenta", "Maroon", "MediumAquaMarine", "MediumBlue", "MediumOrchid", "MediumPurple", "MediumSeaGreen", "MediumSlateBlue", "MediumSpringGreen", "MediumTurquoise", "MediumVioletRed", "MidnightBlue", "MintCream", "MistyRose", "Moccasin", "NavajoWhite", "Navy", "OldLace", "Olive", "OliveDrab", "Orange", "OrangeRed", "Orchid", "PaleGoldenRod", "PaleGreen", "PaleTurquoise", "PaleVioletRed", "PapayaWhip", "PeachPuff", "Peru", "Pink", "Plum", "PowderBlue", "Purple", "RebeccaPurple", "Red", "RosyBrown", "RoyalBlue", "SaddleBrown", "Salmon", "SandyBrown", "SeaGreen", "SeaShell", "Sienna", "Silver", "SkyBlue", "SlateBlue", "SlateGray", "SlateGrey", "Snow", "SpringGreen", "SteelBlue", "Tan", "Teal", "Thistle", "Tomato", "Turquoise", "Violet", "Wheat", "White", "WhiteSmoke", "Yellow", "YellowGreen" };
var colorHex = new List { "f0f8ff", "faebd7", "00ffff", "7fffd4", "f0ffff", "f5f5dc", "ffe4c4", "000000", "ffebcd", "0000ff", "8a2be2", "a52a2a", "deb887", "5f9ea0", "7fff00", "d2691e", "ff7f50", "6495ed", "fff8dc", "dc143c", "00ffff", "00008b", "008b8b", "b8860b", "a9a9a9", "a9a9a9", "006400", "bdb76b", "8b008b", "556b2f", "ff8c00", "9932cc", "8b0000", "e9967a", "8fbc8f", "483d8b", "2f4f4f", "2f4f4f", "00ced1", "9400d3", "ff1493", "00bfff", "696969", "696969", "1e90ff", "b22222", "fffaf0", "228b22", "ff00ff", "dcdcdc", "f8f8ff", "ffd700", "daa520", "808080", "808080", "008000", "adff2f", "f0fff0", "ff69b4", "cd5c5c", "4b0082", "fffff0", "f0e68c", "e6e6fa", "fff0f5", "7cfc00", "fffacd", "add8e6", "f08080", "e0ffff", "fafad2", "d3d3d3", "d3d3d3", "90ee90", "ffb6c1", "ffa07a", "20b2aa", "87cefa", "778899", "778899", "b0c4de", "ffffe0", "00ff00", "32cd32", "faf0e6", "ff00ff", "800000", "66cdaa", "0000cd", "ba55d3", "9370db", "3cb371", "7b68ee", "00fa9a", "48d1cc", "c71585", "191970", "f5fffa", "ffe4e1", "ffe4b5", "ffdead", "000080", "fdf5e6", "808000", "6b8e23", "ffa500", "ff4500", "da70d6", "eee8aa", "98fb98", "afeeee", "db7093", "ffefd5", "ffdab9", "cd853f", "ffc0cb", "dda0dd", "b0e0e6", "800080", "663399", "ff0000", "bc8f8f", "4169e1", "8b4513", "fa8072", "f4a460", "2e8b57", "fff5ee", "a0522d", "c0c0c0", "87ceeb", "6a5acd", "708090", "708090", "fffafa", "00ff7f", "4682b4", "d2b48c", "008080", "d8bfd8", "ff6347", "40e0d0", "ee82ee", "f5deb3", "ffffff", "f5f5f5", "ffff00", "9acd32" };
var findIndx = colorName.IndexOf(name);
if (findIndx != -1)
{
hex = colorHex[findIndx];
}
return hex;
}
public static string GetFillType(XmlNode node)
{
//Need to test/////////////////////////////////////////////
//SOLID_FILL
//PIC_FILL
//GRADIENT_FILL
//PATTERN_FILL
//NO_FILL
var fillType = "";
if (node.GetTextByPath("a:noFill") != null)
{
fillType = "NO_FILL";
}
if (node.GetTextByPath("a:solidFill") != null)
{
fillType = "SOLID_FILL";
}
if (node.GetTextByPath("a:gradFill") != null)
{
fillType = "GRADIENT_FILL";
}
if (node.GetTextByPath("a:pattFill") != null)
{
fillType = "PATTERN_FILL";
}
if (node.GetTextByPath("a:blipFill") != null)
{
fillType = "PIC_FILL";
}
if (fillType == "")
{
var clrName = node.GetTextByPath("p:style/a:fillRef");
if (clrName != null)
{
fillType = "SOLID_FILL";
}
}
return fillType;
}
}
}