ShapeHelper.cs 41 KB

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