ShapeHelper.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  1. using HiTeachCC.Model.PowerPoint;
  2. using HiTeachCC.Service.PowerPoint.Implement;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Xml;
  8. using TEAMModelOS.SDK.Helper.Common.ColorHelper;
  9. using TEAMModelOS.Service.Models.PowerPoint.Inner;
  10. namespace TEAMModelOS.Service.Services.PowerPoint.Implement
  11. {
  12. public static class ShapeHelper
  13. {
  14. private const double px96 = 96.00, px72 = 72.00, px914400 = 914400.00, px12700 = 12700.00;
  15. private const double rot60000 = 60000.00;
  16. public static Border GetBorder(XmlNode node, bool isSvgMode, string bType, Dictionary<string, string> slideLayoutClrOvride, XmlNode themeContent)
  17. {
  18. Border border = new Border();
  19. string cssText = "";
  20. XmlNode lineNode = null;
  21. if (bType == "shape")
  22. {
  23. cssText = "border: ";
  24. lineNode = node.GetTextByPath( "p:spPr/a:ln");// node["p:spPr"]["a:ln"];
  25. }
  26. else if (bType == "text")
  27. {
  28. cssText = "";
  29. lineNode = PowerPointHelper.GetTextByPath(node, "a:rPr/a:ln");// node["a:rPr"]["a:ln"];
  30. }
  31. if (lineNode == null)
  32. {
  33. return null;
  34. }
  35. var borderWidth = 0.0;
  36. XmlNode wnode = lineNode.GetTextByPath("@w");
  37. if (wnode != null)
  38. {
  39. borderWidth = double.Parse(wnode.Value) / px12700;
  40. }
  41. // Border width: 1pt = 12700, default = 0.75pt
  42. // borderWidth = double.Parse(PowerPointHelper.GetTextByPath(lineNode, "@w").Value) / px12700;
  43. if (wnode != null || borderWidth < 1)
  44. {
  45. cssText += "0pt ";
  46. }
  47. else
  48. {
  49. cssText += borderWidth + "pt ";
  50. }
  51. // Border type
  52. var borderType = PowerPointHelper.GetTextByPath(lineNode, "a:prstDash/@val");
  53. var strokeDasharray = "0";
  54. if (borderType != null) {
  55. switch (borderType.Value)
  56. {
  57. case "solid":
  58. cssText += "solid";
  59. strokeDasharray = "0";
  60. break;
  61. case "dash":
  62. cssText += "dashed";
  63. strokeDasharray = "5";
  64. break;
  65. case "dashDot":
  66. cssText += "dashed";
  67. strokeDasharray = "5, 5, 1, 5";
  68. break;
  69. case "dot":
  70. cssText += "dotted";
  71. strokeDasharray = "1, 5";
  72. break;
  73. case "lgDash":
  74. cssText += "dashed";
  75. strokeDasharray = "10, 5";
  76. break;
  77. case "lgDashDotDot":
  78. cssText += "dashed";
  79. strokeDasharray = "10, 5, 1, 5, 1, 5";
  80. break;
  81. case "sysDash":
  82. cssText += "dashed";
  83. strokeDasharray = "5, 2";
  84. break;
  85. case "sysDashDot":
  86. cssText += "dashed";
  87. strokeDasharray = "5, 2, 1, 5";
  88. break;
  89. case "sysDashDotDot":
  90. cssText += "dashed";
  91. strokeDasharray = "5, 2, 1, 5, 1, 5";
  92. break;
  93. case "sysDot":
  94. cssText += "dotted";
  95. strokeDasharray = "2, 5";
  96. break;
  97. case null:
  98. //console.log(borderType);
  99. default:
  100. cssText += "solid";
  101. strokeDasharray = "0";
  102. break;
  103. }
  104. }
  105. // Border color
  106. string borderColorstr = "";
  107. var borderColor = PowerPointHelper.GetTextByPath(lineNode, "a:solidFill/a:srgbClr/@val");
  108. if (borderColor == null)
  109. {
  110. var schemeClrNode = PowerPointHelper.GetTextByPathList(lineNode, "a:solidFill/a:schemeClr");
  111. if (schemeClrNode != null)
  112. {
  113. var schemeClr = PowerPointHelper.GetTextByPath(lineNode, "a:solidFill/a:schemeClr/@val");
  114. borderColorstr = GetSchemeColorFromTheme(schemeClr.Value, null ,slideLayoutClrOvride,themeContent);
  115. }
  116. }
  117. // 2. drawingML namespace
  118. if (borderColor == null)
  119. {
  120. var schemeClrNode = PowerPointHelper.GetTextByPathList(node, "p:style/a:lnRef/a:schemeClr");
  121. if (schemeClrNode != null)
  122. {
  123. var schemeClr = PowerPointHelper.GetTextByPath(node, "p:style/a:lnRef/a:schemeClr/@val");
  124. if (schemeClr != null) {
  125. borderColorstr = GetSchemeColorFromTheme(schemeClr.Value, null, slideLayoutClrOvride, themeContent);
  126. }
  127. }
  128. if (borderColor != null)
  129. {
  130. var shade = PowerPointHelper.GetTextByPath(node, "p:style/a:lnRef/a:schemeClr/a:shade/@val");
  131. if (shade != null)
  132. {
  133. double shaded = double.Parse(shade.Value) / 100000.0;
  134. var color = ColorTranslator.FromHtml("#" + borderColor);
  135. ColorHSL colorHSL = ColorHelper.RgbToHsl(new ColorRGB(color.R, color.G, color.B));
  136. colorHSL.L = colorHSL.L * shaded;
  137. ColorRGB colorRGB = colorHSL.HslToRgb();
  138. borderColorstr = ColorTranslator.ToHtml(Color.FromArgb(colorRGB.R, colorRGB.G, colorRGB.B));
  139. // borderColor = color.hex.replace("#", "");
  140. }
  141. }
  142. }
  143. if (borderColor == null)
  144. {
  145. if (isSvgMode)
  146. {
  147. borderColorstr = "none";
  148. }
  149. else
  150. {
  151. borderColorstr = "#000";
  152. }
  153. }
  154. else
  155. {
  156. borderColorstr = "#" + borderColorstr;
  157. }
  158. cssText += " " + borderColor + " ";
  159. if (borderType != null)
  160. {
  161. if (isSvgMode)
  162. {
  163. return new Border { Color = borderColorstr, Width = (int)borderWidth, Type = borderType.Value, Stroke = strokeDasharray };
  164. }
  165. else
  166. {
  167. return border;
  168. }
  169. }
  170. else {
  171. if (isSvgMode)
  172. {
  173. return new Border { Color = borderColorstr, Width = (int)borderWidth, Type ="", Stroke = strokeDasharray };
  174. }
  175. else
  176. {
  177. return border;
  178. }
  179. }
  180. }
  181. public static string GetSchemeColorFromTheme(string schemeClr, XmlNode sldMasterNode , Dictionary<string ,string > slideLayoutClrOvride ,XmlNode themeContent)
  182. {
  183. //<p:clrMap ...> in slide master
  184. // e.g. tx2="dk2" bg2="lt2" tx1="dk1" bg1="lt1" slideLayoutClrOvride
  185. if (slideLayoutClrOvride == null || slideLayoutClrOvride.Count <= 0)
  186. {
  187. if (sldMasterNode != null)
  188. {
  189. var sldLayoutClrOvr = PowerPointHelper.GetTextByPath(sldMasterNode, "p:sldMaster/p:clrMap");
  190. if (sldLayoutClrOvr != null)
  191. {
  192. //获取 overrideClrMapping所有属性节点 检查测试 是否slideLayoutClrOvride 需要被覆盖
  193. slideLayoutClrOvride = new Dictionary<string, string>() {
  194. { "accent1", sldLayoutClrOvr.GetTextByPath("@accent1").Value},
  195. { "accent2", sldLayoutClrOvr.GetTextByPath("@accent2").Value},
  196. { "accent3", sldLayoutClrOvr.GetTextByPath("@accent3").Value},
  197. { "accent4", sldLayoutClrOvr.GetTextByPath("@accent4").Value},
  198. { "accent5", sldLayoutClrOvr.GetTextByPath("@accent5").Value},
  199. { "accent6", sldLayoutClrOvr.GetTextByPath("@accent6").Value},
  200. { "bg1", sldLayoutClrOvr.GetTextByPath("@bg1").Value},
  201. { "bg2", sldLayoutClrOvr.GetTextByPath("@bg2").Value},
  202. { "folHlink", sldLayoutClrOvr.GetTextByPath("@folHlink").Value},
  203. { "hlink", sldLayoutClrOvr.GetTextByPath("@hlink").Value},
  204. { "tx1", sldLayoutClrOvr.GetTextByPath("@tx1").Value},
  205. { "tx2", sldLayoutClrOvr.GetTextByPath("@tx2").Value}
  206. };
  207. }
  208. }
  209. }
  210. if (!schemeClr.StartsWith("a:"))
  211. {
  212. schemeClr = "a:" + schemeClr;
  213. }
  214. //console.log(slideLayoutClrOvride);
  215. var schmClrName = schemeClr.Replace("a:", "");
  216. if (slideLayoutClrOvride != null)
  217. {
  218. switch (schmClrName)
  219. {
  220. case "tx1":
  221. case "tx2":
  222. case "bg1":
  223. case "bg2":
  224. schemeClr = "a:" + slideLayoutClrOvride[schmClrName];
  225. //schemeClr = "a:" + slideLayoutClrOvride[schmClrName];
  226. //console.log(schmClrName+ "=> "+schemeClr);
  227. break;
  228. }
  229. }
  230. else
  231. {
  232. switch (schmClrName)
  233. {
  234. case "tx1":
  235. schemeClr = "a:dk1";
  236. break;
  237. case "tx2":
  238. schemeClr = "a:dk2";
  239. break;
  240. case "bg1":
  241. schemeClr = "a:lt1";
  242. break;
  243. case "bg2":
  244. schemeClr = "a:lt2";
  245. break;
  246. }
  247. }
  248. //var refNode = PowerPointHelper.GetTextByPathList(themeContent, "a:theme/a:themeElements/a:clrScheme/"+ schemeClr.Value);
  249. var color = PowerPointHelper.GetTextByPath(themeContent, "pkg:xmlData/a:theme/a:themeElements/a:clrScheme/" + schemeClr + "/a:srgbClr/@val");
  250. if (color == null)//&& refNode != null
  251. {
  252. color = PowerPointHelper.GetTextByPath(themeContent, "pkg:xmlData/a:theme/a:themeElements/a:clrScheme/" + schemeClr + "/a:sysClr/@lastClr");
  253. }
  254. //console.log(color)
  255. return color.Value;
  256. }
  257. public static string GetSvgImagePattern(string fillColor, int shpId)
  258. {
  259. var ptrn = "<pattern id=\"imgPtrn_" + shpId + "\"patternContentUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">";// '<pattern id="imgPtrn_' + shpId + '" patternContentUnits="objectBoundingBox" width="1" height="1">';
  260. ptrn += "<image xlink:href=\"" + fillColor + "\"preserveAspectRatio=\"none\" width=\"1\" height=\"1\"></image>";// '<image xlink:href="' + fillColor + '" preserveAspectRatio="none" width="1" height="1"></image>';
  261. ptrn += "</pattern>";// '';
  262. return ptrn;
  263. }
  264. public static string GetSvgGradient(double w, double h, double angl, List<string> color_arry, int shpId, Dictionary<string, string> slideLayoutClrOvride, XmlNode themeContent)
  265. {
  266. var stopsArray = GetMiddleStops(color_arry.Count - 2);
  267. var svgAngle = "";
  268. double svgHeight = h;
  269. double svgWidth = w;
  270. string svg = "";
  271. List<double> xy_ary = SVGangle(angl, svgHeight, svgWidth, slideLayoutClrOvride, themeContent);
  272. double x1 = xy_ary[0];
  273. double y1 = xy_ary[1];
  274. double x2 = xy_ary[2];
  275. double y2 = xy_ary[3];
  276. var sal = stopsArray.Count;
  277. double sr = sal < 20 ? 100 : 1000;
  278. svgAngle = " gradientUnits=\"userSpaceOnUse\" x1=\"" + x1 + "%\" y1=\"" + y1 + "%\" x2=\"" + x2 + "%\" y2=\"" + y2 + "%\"";
  279. svgAngle = "<linearGradient id=\"linGrd_" + shpId + "\"" + svgAngle + ">\n";
  280. svg += svgAngle;
  281. for (var i = 0; i < sal; i++)
  282. {
  283. svg += "<stop offset=\"" + (System.Math.Round(double.Parse(stopsArray[i].Replace("%",""))) / 100 * sr) / sr + "\" stop-color=\"" + color_arry[i] + "\"";
  284. svg += "/>\n";
  285. }
  286. svg += "</linearGradient>\n" + "";
  287. return svg;
  288. }
  289. public static List<string> GetMiddleStops(int s)
  290. {
  291. var sArry = new List<string> { "0%" };
  292. if (s == 0)
  293. {
  294. return sArry;
  295. }
  296. else
  297. {
  298. for (int i = s; i < 0; i--)
  299. {
  300. 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.
  301. var middleStopString = middleStop + "%";
  302. sArry.Add(middleStopString);
  303. // sArry.splice(-1, 0, middleStopString);
  304. }
  305. // AM: add into stopsArray before 100%
  306. }
  307. sArry.Add("100%");
  308. return sArry;
  309. }
  310. public static List<double> SVGangle(double deg, double svgHeight, double svgWidth , Dictionary<string, string> slideLayoutClrOvride, XmlNode themeContent)
  311. {
  312. double w = svgWidth;
  313. double h = svgHeight;
  314. double ang = deg;
  315. double o = 2;
  316. double n = 2;
  317. double wc = w / 2;
  318. double hc = h / 2;
  319. double tx1 = 2;
  320. double ty1 = 2;
  321. double tx2 = 2;
  322. double ty2 = 2;
  323. double k = (((ang % 360) + 360) % 360);
  324. double j = (360 - k) * System.Math.PI / 180;
  325. double i = System.Math.Tan(j);
  326. double l = hc - i * wc;
  327. if (k == 0)
  328. {
  329. tx1 = w;
  330. ty1 = hc;
  331. tx2 = 0;
  332. ty2 = hc;
  333. }
  334. else if (k < 90)
  335. {
  336. n = w;
  337. o = 0;
  338. }
  339. else if (k == 90)
  340. {
  341. tx1 = wc;
  342. ty1 = 0;
  343. tx2 = wc;
  344. ty2 = h;
  345. }
  346. else if (k < 180)
  347. {
  348. n = 0;
  349. o = 0;
  350. }
  351. else if (k == 180)
  352. {
  353. tx1 = 0;
  354. ty1 = hc;
  355. tx2 = w;
  356. ty2 = hc;
  357. }
  358. else if (k < 270)
  359. {
  360. n = 0;
  361. o = h;
  362. }
  363. else if (k == 270)
  364. {
  365. tx1 = wc;
  366. ty1 = h;
  367. tx2 = wc;
  368. ty2 = 0;
  369. }
  370. else
  371. {
  372. n = w;
  373. o = h;
  374. }
  375. // AM: I could not quite figure out what m, n, and o are supposed to represent from the original code on visualcsstools.com.
  376. var m = o + (n / i);
  377. tx1 = tx1 == 2 ? i * (m - l) / (System.Math.Pow(i, 2) + 1) : tx1;
  378. ty1 = ty1 == 2 ? i * tx1 + l : ty1;
  379. tx2 = tx2 == 2 ? w - tx1 : tx2;
  380. ty2 = ty2 == 2 ? h - ty1 : ty2;
  381. double x1 = System.Math.Round(tx2 / w * 100 * 100) / 100;
  382. double y1 = System.Math.Round(ty2 / h * 100 * 100) / 100;
  383. double x2 = System.Math.Round(tx1 / w * 100 * 100) / 100;
  384. double y2 = System.Math.Round(ty1 / h * 100 * 100) / 100;
  385. return new List<double> { x1, y1, x2, y2 };
  386. }
  387. public static Fill GetPatternFill(XmlNode node ,Dictionary<string, string> slideLayoutClrOvride, XmlNode slideMasterContent, XmlNode themeContent)
  388. {
  389. Fill fill = new Fill { Type = 4 };
  390. //处理前景色
  391. var fgClr = node.GetTextByPath( "a:fgClr");
  392. string fgclr = GetSolidFill(fgClr, slideLayoutClrOvride, slideMasterContent, themeContent);
  393. fgclr =PowerPointHelper.ColorToning(fgClr.OuterXml, fgclr);
  394. fill.gradColor.Add(fgclr);
  395. // 处理背景色
  396. var bgClr = node.GetTextByPath( "a:bgClr");
  397. string bgclr = GetSolidFill(bgClr, slideLayoutClrOvride, slideMasterContent, themeContent);
  398. bgclr = PowerPointHelper.ColorToning(bgClr.OuterXml, bgclr);
  399. //处理内置图案属性
  400. var prst = node.GetTextByPath("@prst");
  401. if (prst != null) {
  402. fill.pattPrst = prst.Value;
  403. }
  404. fill.gradColor.Add(bgclr);
  405. return fill;
  406. }
  407. public static dynamic GetSlideSize(XmlDocument xdoc)
  408. {
  409. var sldSzNode = xdoc.GetTextByPath("//pkg:part[@pkg:name='/ppt/presentation.xml']/pkg:xmlData/p:presentation/p:sldSz");
  410. double width = double.Parse(sldSzNode.GetTextByPath("@cx").Value) * px96 / px914400;
  411. double height = double.Parse(sldSzNode.GetTextByPath("@cy").Value) * px96 / px914400;
  412. return new { width, height };
  413. }
  414. public static Fill GetGradientFill(XmlNode node, Dictionary<string, string> slideLayoutClrOvride,XmlNode slideMasterContent, XmlNode themeContent)
  415. {
  416. XmlNodeList gsLst = PowerPointHelper.GetTextByPathList(node, "a:gsLst/a:gs");// node["a:gsLst"]["a:gs"];
  417. //get start color
  418. var color_ary = new List<string>();
  419. for (int i = 0; i < gsLst.Count; i++)
  420. {
  421. var lo_color = GetSolidFill(gsLst[i] , slideLayoutClrOvride, slideMasterContent, themeContent);
  422. lo_color = PowerPointHelper.ColorToning(gsLst[i].OuterXml, lo_color);
  423. color_ary.Add(lo_color);
  424. }
  425. //get rot
  426. var lin = PowerPointHelper.GetTextByPathList(node, "a:lin");// node["a:lin"];
  427. double rot = 0;
  428. if (lin != null)
  429. {
  430. rot = AngleToDegrees(PowerPointHelper.GetTextByPath(node, "a:lin/@ang")) + 90;
  431. }
  432. return new Fill()
  433. {
  434. Type = 2,
  435. gradColor = color_ary,
  436. Rot = rot
  437. };
  438. }
  439. public static Position GetPosition(XmlNode slideXfrmNode, XmlNode slideLayoutXfrmNode, XmlNode slideMasterXfrmNode)
  440. {
  441. XmlNode off = null;
  442. XmlNode ext = null;
  443. double x, y,w,h;
  444. //ext
  445. if(slideXfrmNode != null)
  446. {
  447. ext = PowerPointHelper.GetTextByPath(slideXfrmNode, "a:ext");
  448. }
  449. else if (slideLayoutXfrmNode != null && ext == null)
  450. {
  451. ext = PowerPointHelper.GetTextByPath(slideLayoutXfrmNode, "a:ext");
  452. }
  453. else if (slideMasterXfrmNode != null && ext == null)
  454. {
  455. ext = PowerPointHelper.GetTextByPath(slideMasterXfrmNode, "a:ext");
  456. }
  457. //off
  458. if (slideXfrmNode != null)
  459. {
  460. off = PowerPointHelper.GetTextByPath(slideXfrmNode, "a:off");
  461. }
  462. else if (slideLayoutXfrmNode != null && off==null)
  463. {
  464. off = PowerPointHelper.GetTextByPath(slideLayoutXfrmNode, "a:off");
  465. }
  466. else if (slideMasterXfrmNode != null && off == null)
  467. {
  468. off = PowerPointHelper.GetTextByPath(slideMasterXfrmNode, "a:off");
  469. }
  470. x = double.Parse(off.GetTextByPath( "@x").Value) * px96 / px914400;
  471. y = double.Parse(off.GetTextByPath( "@y").Value) * px96 / px914400;
  472. w = double.Parse(ext.GetTextByPath("@cx").Value) * px96 / px914400;
  473. h = double.Parse(ext.GetTextByPath("@cy").Value) * px96 / px914400;
  474. return new Position()
  475. {
  476. Cx=w,
  477. Cy=h,
  478. X = x,
  479. Y = y
  480. };
  481. }
  482. public static NodesTable IndexNodes(XmlNode content)
  483. {
  484. var idTable = new Dictionary<string, XmlNode>();
  485. var idxTable = new Dictionary<string, XmlNode>();
  486. var typeTable = new Dictionary<string, XmlNode>();
  487. var spTreeNode = content.GetTextByPath("p:cSld/p:spTree");
  488. // Dictionary<string, Dictionary<string, string>> slideResObj = new Dictionary<string, Dictionary<string, string>>();
  489. var spTreeNodeChildren = spTreeNode.ChildNodes;
  490. foreach (XmlNode child in spTreeNodeChildren)
  491. {
  492. if (child.Name.Equals("p:nvGrpSpPr") || child.Name.Equals("p:grpSpPr"))
  493. {
  494. continue;
  495. }
  496. //var targetNode = child.ChildNodes;
  497. var targetNode = child.GetTextByPath("p:nvSpPr");
  498. // < p:cNvCxnSpPr >
  499. // < a:cxnSpLocks /> ///这个是什么意思
  500. // </ p:cNvCxnSpPr >
  501. if (targetNode == null)
  502. {
  503. targetNode = child.GetTextByPath("p:nvCxnSpPr");
  504. }
  505. var id = targetNode.GetTextByPath("p:cNvPr/@id");
  506. var idx = targetNode.GetTextByPath("p:nvPr/p:ph/@idx");
  507. var type = targetNode.GetTextByPath("p:nvPr/p:ph/@type");
  508. // Dictionary<string, XmlNode> node = new Dictionary<string, XmlNode>();
  509. //if (child.ChildNodes != null)
  510. //{
  511. // foreach (XmlNode xmlNode in child.ChildNodes)
  512. // {
  513. // node.TryAdd(xmlNode.Name, xmlNode);
  514. // }
  515. //}
  516. if (id != null)
  517. {
  518. idTable[id.Value] = child;
  519. }
  520. if (idx != null)
  521. {
  522. idxTable[idx.Value] = child;
  523. }
  524. if (type != null)
  525. {
  526. ///会出现相同Key
  527. typeTable[type.Value] = child;
  528. }
  529. }
  530. return new NodesTable { idTable = idTable, idxTable = idxTable, typeTable = typeTable };
  531. }
  532. public static double AngleToDegrees(XmlNode angle)
  533. {
  534. if (angle == null)
  535. {
  536. return 0;
  537. }
  538. return double.Parse(angle.Value) / 60000.00;
  539. }
  540. public static XmlNode GetNodesTable(XmlNode id, XmlNode idx, XmlNode type, WarpObj warpObj, string LayoutOrMaster)
  541. {
  542. XmlNode resNode = null;
  543. if (resNode == null)
  544. {
  545. if (id != null)
  546. {
  547. if (LayoutOrMaster.Equals("Layout"))
  548. {
  549. if (warpObj.slideLayoutTables.idTable.TryGetValue(id.Value, out XmlNode LayoutNode))
  550. {
  551. // LayoutNode.TryGetValue(id.Value, out XmlNode node);
  552. resNode = LayoutNode;
  553. };
  554. }
  555. if (LayoutOrMaster.Equals("Master"))
  556. {
  557. if (warpObj.slideMasterTables.idTable.TryGetValue(id.Value, out XmlNode MasterNode))
  558. {
  559. // LayoutNode.TryGetValue(id.Value, out XmlNode node);
  560. resNode = MasterNode;
  561. };
  562. }
  563. }
  564. }
  565. if (resNode == null)
  566. {
  567. if (idx != null)
  568. {
  569. if (LayoutOrMaster.Equals("Layout"))
  570. {
  571. if (warpObj.slideLayoutTables.idxTable.TryGetValue(idx.Value, out XmlNode LayoutNode))
  572. {
  573. //LayoutNode.TryGetValue(idx.Value, out XmlNode node);
  574. resNode = LayoutNode;
  575. };
  576. }
  577. if (LayoutOrMaster.Equals("Master"))
  578. {
  579. if (warpObj.slideMasterTables.idxTable.TryGetValue(idx.Value, out XmlNode MasterNode))
  580. {
  581. // LayoutNode.TryGetValue(idx.Value, out XmlNode node);
  582. resNode = MasterNode;
  583. };
  584. }
  585. }
  586. }
  587. if (resNode == null)
  588. {
  589. if (type != null)
  590. {
  591. if (LayoutOrMaster.Equals("Layout"))
  592. {
  593. if (warpObj.slideLayoutTables.typeTable.TryGetValue(type.Value, out XmlNode LayoutNode))
  594. {
  595. // LayoutNode.TryGetValue(type.Value, out XmlNode node);
  596. resNode = LayoutNode;
  597. };
  598. }
  599. if (LayoutOrMaster.Equals("Master"))
  600. {
  601. if (warpObj.slideMasterTables.typeTable.TryGetValue(type.Value, out XmlNode MasterNode))
  602. {
  603. // MasterNode.TryGetValue(type.Value, out XmlNode node);
  604. resNode = MasterNode;
  605. };
  606. }
  607. }
  608. }
  609. return resNode;
  610. }
  611. public static string HexToRgbNew(string bgColor)
  612. {
  613. //var arrBuff = new ArrayBuffer(4);
  614. //var vw = new DataView(arrBuff);
  615. //vw.setUint32(0, parseInt(hex, 16), false);
  616. //var arrByte = new Uint8Array(arrBuff);
  617. int r = Convert.ToInt32("0x" + bgColor.Substring(0, 2), 16);
  618. int g = Convert.ToInt32("0x" + bgColor.Substring(2, 2), 16);
  619. int b = Convert.ToInt32("0x" + bgColor.Substring(4, 2), 16);
  620. return r + "," + g + "," + b;
  621. }
  622. public static double GetColorOpacity(XmlNode solidFill)
  623. {
  624. double opcity = 1;
  625. if (solidFill == null)
  626. {
  627. return opcity;
  628. }
  629. if (solidFill.GetTextByPath("a:srgbClr") != null)
  630. {
  631. var tint = solidFill.GetTextByPath("a:srgbClr/a:tint/@val");
  632. if (tint != null)
  633. {
  634. opcity = double.Parse(tint.Value) / 100000;
  635. }
  636. }
  637. else if (solidFill.GetTextByPath("a:schemeClr") != null)
  638. {
  639. var tint = solidFill.GetTextByPath("a:schemeClr/a:tint/@val");
  640. if (tint != null)
  641. {
  642. opcity = double.Parse(tint.Value) / 100000;
  643. }
  644. }
  645. else if (solidFill.GetTextByPath("a:scrgbClr") != null)
  646. {
  647. var tint = solidFill.GetTextByPath("a:scrgbClr/a:tint/@val");
  648. if (tint != null)
  649. {
  650. opcity = double.Parse(tint.Value) / 100000;
  651. }
  652. }
  653. else if (solidFill.GetTextByPath("a:prstClr") != null)
  654. {
  655. var tint = solidFill.GetTextByPath("a:prstClr/a:tint/@val");
  656. if (tint != null)
  657. {
  658. opcity = double.Parse(tint.Value) / 100000;
  659. }
  660. }
  661. else if (solidFill.GetTextByPath("a:hslClr") != null)
  662. {
  663. var tint = solidFill.GetTextByPath("a:hslClr/a:tint/@val");
  664. if (tint != null)
  665. {
  666. opcity = double.Parse(tint.Value) / 100000;
  667. }
  668. }
  669. else if (solidFill.GetTextByPath("a:sysClr") != null)
  670. {
  671. var tint = solidFill.GetTextByPath("a:sysClr/a:tint/@val");
  672. if (tint != null)
  673. {
  674. opcity = double.Parse(tint.Value) / 100000;
  675. }
  676. }
  677. return opcity;
  678. }
  679. public static Fill GetBgGradientFill(XmlNode bgPr, string phClr, Dictionary<string ,string > slideLayoutClrOvride, XmlNode slideMasterContent, XmlNode themeContent)
  680. {
  681. if (bgPr != null)
  682. {
  683. var grdFill = bgPr.GetTextByPath("a:gradFill");
  684. return GetGradientFill(grdFill, slideLayoutClrOvride, slideMasterContent, themeContent);
  685. }
  686. else
  687. {
  688. if (phClr == null)
  689. {
  690. return new Fill { Type = 1, Color = phClr };
  691. }
  692. }
  693. return null;
  694. }
  695. public static string GetSolidFill(XmlNode node, Dictionary<string, string> slideLayoutClrOvride, XmlNode slideMasterContent, XmlNode themeContent)
  696. {
  697. if (node == null)
  698. {
  699. return null;
  700. }
  701. string Color = "FFF";
  702. // Fill fill = new Fill() { Color = "FFF", Type = 1 };
  703. var srgbClrval = node.GetTextByPath("a:srgbClr/@val");
  704. var schemeClrval = node.GetTextByPath("a:schemeClr/@val");
  705. if (srgbClrval != null)
  706. {
  707. Color = srgbClrval.Value; //#...
  708. }
  709. else if (schemeClrval != null)//node["a:schemeClr"] != null)
  710. {
  711. //a:schemeClr
  712. // var schemeClr = PowerPointHelper.GetTextByPath(node, "a:schemeClr/@val");
  713. //console.log(schemeClr)
  714. Color = ShapeHelper.GetSchemeColorFromTheme(schemeClrval.Value, slideMasterContent, slideLayoutClrOvride, themeContent); //#...
  715. }
  716. else if (PowerPointHelper.GetTextByPath(node, "a:scrgbClr") != null)
  717. {
  718. //<a:scrgbClr r="50%" g="50%" b="50%"/> //Need to test/////////////////////////////////////////////
  719. var defBultColorValsR = PowerPointHelper.GetTextByPath(node, "a:scrgbClr/@r");
  720. var defBultColorValsG = PowerPointHelper.GetTextByPath(node, "a:scrgbClr/@g");
  721. var defBultColorValsB = PowerPointHelper.GetTextByPath(node, "a:scrgbClr/@b");
  722. var red = (defBultColorValsR.Value.IndexOf("%") != -1) ? defBultColorValsR.Value.Split("%").First() : defBultColorValsR.Value;
  723. var green = (defBultColorValsG.Value.IndexOf("%") != -1) ? defBultColorValsG.Value.Split("%").First() : defBultColorValsG.Value;
  724. var blue = (defBultColorValsB.Value.IndexOf("%") != -1) ? defBultColorValsB.Value.Split("%").First() : defBultColorValsB.Value;
  725. var scrgbClr = red + "," + green + "," + blue;
  726. Color = ToHex(255 * (double.Parse(red) / 100)) + ToHex(255 * (double.Parse(green) / 100)) + ToHex(255 * (double.Parse(blue) / 100));
  727. //console.log("scrgbClr: " + scrgbClr);
  728. }
  729. else if (PowerPointHelper.GetTextByPath(node, "a:prstClr") != null)
  730. {
  731. //<a:prstClr val="black"/> //Need to test/////////////////////////////////////////////
  732. var prstClr = PowerPointHelper.GetTextByPath(node, "a:prstClr/@val");// node["a:prstClr"]["attrs"]["val"];
  733. Color = GetColorName2Hex(prstClr.Value);
  734. //console.log("prstClr: " + prstClr+" => hexClr: "+color);
  735. }
  736. else if (PowerPointHelper.GetTextByPath(node, "a:hslClr") != null)
  737. {
  738. //<a:hslClr hue="14400000" sat="100%" lum="50%"/> //Need to test/////////////////////////////////////////////
  739. var defBultColorVals = PowerPointHelper.GetTextByPath(node, "a:hslClr");//["attrs"];
  740. var defBultColorVals_hue = PowerPointHelper.GetTextByPath(defBultColorVals, "@hue");
  741. var defBultColorVals_sat = PowerPointHelper.GetTextByPath(defBultColorVals, "@sat");
  742. var defBultColorVals_lum = PowerPointHelper.GetTextByPath(defBultColorVals, "@lum");
  743. var hue = double.Parse(defBultColorVals_hue.Value) / 100000;
  744. var sat = double.Parse((defBultColorVals_sat.Value.IndexOf("%") != -1) ? defBultColorVals_sat.Value.Split("%").First() : defBultColorVals_sat.Value) / 100;
  745. var lum = double.Parse((defBultColorVals_lum.Value.IndexOf("%") != -1) ? defBultColorVals_lum.Value.Split("%").First() : defBultColorVals_lum.Value) / 100;
  746. var hslClr = defBultColorVals_hue.Value.ToString() + "," + defBultColorVals_sat.Value.ToString() + "," + defBultColorVals_lum.Value.ToString();
  747. var hsl2rgb = HslToRgb(hue, sat, lum);
  748. Color = ToHex(hsl2rgb.r) + ToHex(hsl2rgb.g) + ToHex(hsl2rgb.b);
  749. //defBultColor = cnvrtHslColor2Hex(hslClr); //TODO
  750. // console.log("hslClr: " + hslClr);
  751. }
  752. else if (PowerPointHelper.GetTextByPath(node, "a:sysClr") != null)
  753. {
  754. //<a:sysClr val="windowText" lastClr="000000"/> //Need to test/////////////////////////////////////////////
  755. var sysClr = PowerPointHelper.GetTextByPath(node, "a:sysClr/@lastClr").Value;
  756. if (sysClr != null)
  757. {
  758. Color = sysClr;
  759. }
  760. }
  761. return Color;
  762. }
  763. public static string ToHex(dynamic n)
  764. {
  765. string hex = n.toString(16);
  766. while (hex.Length < 2) { hex = "0" + hex; }
  767. return hex;
  768. }
  769. public static dynamic HslToRgb(double hue, double sat, double light)
  770. {
  771. double t1, t2, r, g, b;
  772. hue /= 60;
  773. if (light <= 0.5)
  774. {
  775. t2 = light * (sat + 1);
  776. }
  777. else
  778. {
  779. t2 = light + sat - (light * sat);
  780. }
  781. t1 = light * 2 - t2;
  782. r = HueToRgb(t1, t2, hue + 2) * 255;
  783. g = HueToRgb(t1, t2, hue) * 255;
  784. b = HueToRgb(t1, t2, hue - 2) * 255;
  785. return new { r, g, b };
  786. }
  787. public static double HueToRgb(double t1, double t2, double hue)
  788. {
  789. if (hue < 0) hue += 6;
  790. if (hue >= 6) hue -= 6;
  791. if (hue < 1) return (t2 - t1) * hue + t1;
  792. else if (hue < 3) return t2;
  793. else if (hue < 4) return (t2 - t1) * (4 - hue) + t1;
  794. else return t1;
  795. }
  796. public static string GetColorName2Hex(string name)
  797. {
  798. var hex = "";
  799. var colorName = new List<string> { "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" };
  800. var colorHex = new List<string> { "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" };
  801. var findIndx = colorName.IndexOf(name);
  802. if (findIndx != -1)
  803. {
  804. hex = colorHex[findIndx];
  805. }
  806. return hex;
  807. }
  808. public static string GetFillType(XmlNode node)
  809. {
  810. //Need to test/////////////////////////////////////////////
  811. //SOLID_FILL
  812. //PIC_FILL
  813. //GRADIENT_FILL
  814. //PATTERN_FILL
  815. //NO_FILL
  816. var fillType = "";
  817. if (node.GetTextByPath("a:noFill") != null)
  818. {
  819. fillType = "NO_FILL";
  820. }
  821. if (node.GetTextByPath("a:solidFill") != null)
  822. {
  823. fillType = "SOLID_FILL";
  824. }
  825. if (node.GetTextByPath("a:gradFill") != null)
  826. {
  827. fillType = "GRADIENT_FILL";
  828. }
  829. if (node.GetTextByPath("a:pattFill") != null)
  830. {
  831. fillType = "PATTERN_FILL";
  832. }
  833. if (node.GetTextByPath("a:blipFill") != null)
  834. {
  835. fillType = "PIC_FILL";
  836. }
  837. return fillType;
  838. }
  839. }
  840. }