PageRenderTime 346ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/WordToXaml.VS2013/WordToXamlLibrary/TransformUtilities.cs

#
C# | 247 lines | 159 code | 45 blank | 43 comment | 25 complexity | b946ad0993db8f41cc0a0e405360c93b MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. // <copyright file="TransformUtilities.cs" company="Microsoft Corporation">
  2. // Copyright (c) 2008 All Right Reserved
  3. // </copyright>
  4. // <author>Michael S. Scherotter</author>
  5. // <email>mischero@microsoft.com</email>
  6. // <date>2009-01-29</date>
  7. // <summary>Transformation utilities used as an extension object during XSL Transformation</summary>
  8. namespace Synergist.WordToXamlLibrary
  9. {
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Globalization;
  13. using System.Linq;
  14. using System.Text;
  15. /// <summary>
  16. /// Transformation utilities used as an extension object during XSL Transformation
  17. /// </summary>
  18. public class TransformUtilities
  19. {
  20. /// <summary>
  21. /// Substitute all { for {{ and all } for }} so XAML text parses correctly.
  22. /// </summary>
  23. /// <param name="input">a possibly dirty XAML string.</param>
  24. /// <returns>a clean XAML string</returns>
  25. /// <remarks>This will work for all text except for text with the brackets reversed like this: } { </remarks>
  26. public string CleanXaml(string input)
  27. {
  28. if (input == null)
  29. {
  30. throw new ArgumentNullException("input");
  31. }
  32. string value = input.Replace("{", "{}{");
  33. return value;
  34. }
  35. /// <summary>
  36. /// Given an offset determine the length in 96 DPI Pixels
  37. /// </summary>
  38. /// <param name="offset">an offset string</param>
  39. /// <returns>the length in 96 DPI pixels to the offset</returns>
  40. public double GetLength(string offset)
  41. {
  42. var pt = GetPoint(offset);
  43. return Math.Sqrt(Math.Pow(pt[0], 2) + Math.Pow(pt[1], 2));
  44. }
  45. /// <summary>
  46. /// Given an offset, determine the angle from 0 to 360 with 0 being the positive X Axis
  47. /// </summary>
  48. /// <param name="offset">an offset like '3pt,2pt' or ',4pt'</param>
  49. /// <returns>the angle in degrees</returns>
  50. public double GetAngle(string offset)
  51. {
  52. var pt = GetPoint(offset);
  53. var radians = Math.Atan2(-pt[1], pt[0]);
  54. var degrees = radians * 180 / Math.PI;
  55. if (degrees < 0.0)
  56. {
  57. degrees += 360;
  58. }
  59. return degrees;
  60. }
  61. /// <summary>
  62. /// Returns the corner radius string for a Border
  63. /// </summary>
  64. /// <param name="arcSize">the arc size string as a percentage or a fixed precision number (f suffix)</param>
  65. /// <param name="widthValue">the width of the element</param>
  66. /// <param name="heightValue">the height of the element</param>
  67. /// <returns>the corner radius in 96 DPI pixels</returns>
  68. public string CornerRadius(string arcSize, string widthValue, string heightValue)
  69. {
  70. if (string.IsNullOrEmpty(widthValue))
  71. {
  72. throw new ArgumentNullException("widthValue");
  73. }
  74. if (string.IsNullOrEmpty(heightValue))
  75. {
  76. throw new ArgumentNullException("heightValue");
  77. }
  78. if (string.IsNullOrEmpty(arcSize))
  79. {
  80. throw new ArgumentNullException("arcSize");
  81. }
  82. double width = 0;
  83. double height = 0;
  84. if (widthValue.Contains("pt"))
  85. {
  86. width = double.Parse(widthValue.Substring(0, widthValue.Length - 2), System.Globalization.CultureInfo.InvariantCulture) * 96 / 72;
  87. }
  88. else
  89. {
  90. width = double.Parse(widthValue, System.Globalization.CultureInfo.InvariantCulture) * 96 / 72 / 20;
  91. }
  92. if (heightValue.Contains("pt"))
  93. {
  94. height = double.Parse(heightValue.Substring(0, heightValue.Length - 2), System.Globalization.CultureInfo.InvariantCulture) * 96 / 72;
  95. }
  96. else
  97. {
  98. height = double.Parse(heightValue, System.Globalization.CultureInfo.InvariantCulture) * 96 / 72 / 20;
  99. }
  100. double percentage = 0;
  101. if (arcSize.Contains('f'))
  102. {
  103. percentage = double.Parse(arcSize.Substring(0, arcSize.Length - 1), System.Globalization.CultureInfo.InvariantCulture) / 65536;
  104. }
  105. else if (arcSize.Contains('%'))
  106. {
  107. percentage = double.Parse(arcSize.Substring(0, arcSize.Length - 1), System.Globalization.CultureInfo.InvariantCulture);
  108. }
  109. else
  110. {
  111. percentage = double.Parse(arcSize, System.Globalization.CultureInfo.InvariantCulture);
  112. }
  113. var size = Math.Min(width, height) * percentage;
  114. return size.ToString(CultureInfo.InvariantCulture);
  115. }
  116. /// <summary>
  117. /// Convert a VML v:shapetype/@path string to a WPF Path data string
  118. /// </summary>
  119. /// <param name="vmlPath">a VML path like <![CDATA[m@4@5l@4@11@9@11@9@5xe]]></param>
  120. /// <returns>a WPF path like this: m 4,5 l 4,11 9,11 9,5 z</returns>
  121. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Necessary to be used in XSL Transformation."),
  122. System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "vml", Justification = "vml is an acronym.")]
  123. public string GetPathData(string vmlPath)
  124. {
  125. if (vmlPath == null)
  126. {
  127. return null;
  128. }
  129. System.Diagnostics.Debug.WriteLine("Converting VML Path from " + vmlPath);
  130. var commandKeys = new string[] { "nf", "ns", "ae", "al", "at", "ar", "wa", "wr", "qx", "qy", "qb", "m", "l", "c", "x", "e", "t", "r", "v" };
  131. string path = vmlPath.Replace('@', ' ');
  132. foreach (var commandKey in commandKeys)
  133. {
  134. path = path.Replace(commandKey, " " + commandKey);
  135. }
  136. string[] elements = path.Split(' ');
  137. StringBuilder builder = new StringBuilder();
  138. for (int i = 0; i < elements.Length; i++)
  139. {
  140. switch (elements[i])
  141. {
  142. case "m":
  143. builder.AppendFormat("m {0},{1} ", elements[i + 1], elements[i + 2]);
  144. i += 2;
  145. break;
  146. case "l":
  147. builder.Append("l ");
  148. i++;
  149. do
  150. {
  151. builder.AppendFormat("{0},{1} ", elements[i], elements[i + 1]);
  152. i += 2;
  153. }
  154. while (!commandKeys.Contains(elements[i]));
  155. i--;
  156. break;
  157. case "x":
  158. builder.Append("z");
  159. break;
  160. case "e":
  161. break;
  162. }
  163. }
  164. string wpfPathData = builder.ToString();
  165. System.Diagnostics.Debug.WriteLine("to WPF Path Data: " + wpfPathData);
  166. return wpfPathData;
  167. }
  168. /// <summary>
  169. /// Gets the point for an offset
  170. /// </summary>
  171. /// <param name="offset">the offset string</param>
  172. /// <returns>a double[2] with x and y coordinates</returns>
  173. private static double[] GetPoint(string offset)
  174. {
  175. var xy = offset.Split(',');
  176. double[] point = new double[2];
  177. if (xy[0].Contains("pt"))
  178. {
  179. var xstr = xy[0].Substring(0, xy[0].Length - 2);
  180. point[0] = double.Parse(xstr, System.Globalization.CultureInfo.InvariantCulture) * 96.0 / 72.0;
  181. }
  182. else if (!string.IsNullOrEmpty(xy[0]))
  183. {
  184. point[0] = double.Parse(xy[0], System.Globalization.CultureInfo.InvariantCulture) * 96.0 / 72.0 / 20;
  185. }
  186. if (xy.Length == 1)
  187. {
  188. point[1] = point[0];
  189. }
  190. else if (xy[1].Contains("pt"))
  191. {
  192. var ystr = xy[1].Substring(0, xy[1].Length - 2);
  193. point[1] = double.Parse(ystr, System.Globalization.CultureInfo.InvariantCulture) * 96.0 / 72.0;
  194. }
  195. else if (!string.IsNullOrEmpty(xy[1]))
  196. {
  197. point[1] = double.Parse(xy[1], System.Globalization.CultureInfo.InvariantCulture) * 96.0 / 72.0 / 20;
  198. }
  199. return point;
  200. }
  201. }
  202. }