Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

Formatting.cs 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. using System;
  2. using System.Linq;
  3. using System.Xml.Linq;
  4. using System.Drawing;
  5. using System.Globalization;
  6. namespace Novacode
  7. {
  8. /// <summary>
  9. /// A text formatting.
  10. /// </summary>
  11. public class Formatting : IComparable
  12. {
  13. private XElement rPr;
  14. private bool hidden;
  15. private bool bold;
  16. private bool italic;
  17. private StrikeThrough strikethrough;
  18. private Script script;
  19. private Highlight highlight;
  20. private double? size;
  21. private Color? fontColor;
  22. private Color? underlineColor;
  23. private UnderlineStyle underlineStyle;
  24. private Misc misc;
  25. private CapsStyle capsStyle;
  26. private FontFamily fontFamily;
  27. private int? percentageScale;
  28. private int? kerning;
  29. private int? position;
  30. private double? spacing;
  31. private CultureInfo language;
  32. /// <summary>
  33. /// A text formatting.
  34. /// </summary>
  35. public Formatting()
  36. {
  37. capsStyle = CapsStyle.none;
  38. strikethrough = StrikeThrough.none;
  39. script = Script.none;
  40. highlight = Highlight.none;
  41. underlineStyle = UnderlineStyle.none;
  42. misc = Misc.none;
  43. // Use current culture by default
  44. language = CultureInfo.CurrentCulture;
  45. rPr = new XElement(XName.Get("rPr", DocX.w.NamespaceName));
  46. }
  47. /// <summary>
  48. /// Text language
  49. /// </summary>
  50. public CultureInfo Language
  51. {
  52. get
  53. {
  54. return language;
  55. }
  56. set
  57. {
  58. language = value;
  59. }
  60. }
  61. public static Formatting Parse(XElement rPr)
  62. {
  63. Formatting formatting = new Formatting();
  64. // Build up the Formatting object.
  65. foreach (XElement option in rPr.Elements())
  66. {
  67. switch (option.Name.LocalName)
  68. {
  69. case "lang": formatting.Language = new CultureInfo(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName), null) ?? option.GetAttribute(XName.Get("eastAsia", DocX.w.NamespaceName), null) ?? option.GetAttribute(XName.Get("bidi", DocX.w.NamespaceName))); break;
  70. case "spacing": formatting.Spacing = Double.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 20.0; break;
  71. case "position": formatting.Position = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; break;
  72. case "kern": formatting.Position = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))) / 2; break;
  73. case "w": formatting.PercentageScale = Int32.Parse(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName))); break;
  74. case "rFonts": formatting.FontFamily = new FontFamily(option.GetAttribute(XName.Get("cs", DocX.w.NamespaceName))); break;
  75. case "vanish": formatting.hidden = true; break;
  76. case "b": formatting.Bold = true; break;
  77. case "i": formatting.Italic = true; break;
  78. case "u": formatting.UnderlineStyle = HelperFunctions.GetUnderlineStyle(option.GetAttribute(XName.Get("val", DocX.w.NamespaceName)));
  79. break;
  80. default: break;
  81. }
  82. }
  83. return formatting;
  84. }
  85. internal XElement Xml
  86. {
  87. get
  88. {
  89. rPr = new XElement(XName.Get("rPr", DocX.w.NamespaceName));
  90. if (language != null)
  91. rPr.Add(new XElement(XName.Get("lang", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), language.Name)));
  92. if(spacing.HasValue)
  93. rPr.Add(new XElement(XName.Get("spacing", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), spacing.Value * 20)));
  94. if(position.HasValue)
  95. rPr.Add(new XElement(XName.Get("position", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), position.Value * 2)));
  96. if (kerning.HasValue)
  97. rPr.Add(new XElement(XName.Get("kern", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), kerning.Value * 2)));
  98. if (percentageScale.HasValue)
  99. rPr.Add(new XElement(XName.Get("w", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), percentageScale)));
  100. if (fontFamily != null)
  101. {
  102. rPr.Add
  103. (
  104. new XElement
  105. (
  106. XName.Get("rFonts", DocX.w.NamespaceName),
  107. new XAttribute(XName.Get("ascii", DocX.w.NamespaceName), fontFamily.Name),
  108. new XAttribute(XName.Get("hAnsi", DocX.w.NamespaceName), fontFamily.Name), // Added by Maurits Elbers to support non-standard characters. See http://docx.codeplex.com/Thread/View.aspx?ThreadId=70097&ANCHOR#Post453865
  109. new XAttribute(XName.Get("cs", DocX.w.NamespaceName), fontFamily.Name) // Added by Maurits Elbers to support non-standard characters. See http://docx.codeplex.com/Thread/View.aspx?ThreadId=70097&ANCHOR#Post453865
  110. )
  111. );
  112. }
  113. if(hidden)
  114. rPr.Add(new XElement(XName.Get("vanish", DocX.w.NamespaceName)));
  115. if (bold)
  116. rPr.Add(new XElement(XName.Get("b", DocX.w.NamespaceName)));
  117. if (italic)
  118. rPr.Add(new XElement(XName.Get("i", DocX.w.NamespaceName)));
  119. switch (underlineStyle)
  120. {
  121. case UnderlineStyle.none:
  122. break;
  123. case UnderlineStyle.singleLine:
  124. rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "single")));
  125. break;
  126. case UnderlineStyle.doubleLine:
  127. rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "double")));
  128. break;
  129. default:
  130. rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), underlineStyle.ToString())));
  131. break;
  132. }
  133. if(underlineColor.HasValue)
  134. {
  135. // If an underlineColor has been set but no underlineStyle has been set
  136. if (underlineStyle == UnderlineStyle.none)
  137. {
  138. // Set the underlineStyle to the default
  139. underlineStyle = UnderlineStyle.singleLine;
  140. rPr.Add(new XElement(XName.Get("u", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), "single")));
  141. }
  142. rPr.Element(XName.Get("u", DocX.w.NamespaceName)).Add(new XAttribute(XName.Get("color", DocX.w.NamespaceName), underlineColor.Value.ToHex()));
  143. }
  144. switch (strikethrough)
  145. {
  146. case StrikeThrough.none:
  147. break;
  148. case StrikeThrough.strike:
  149. rPr.Add(new XElement(XName.Get("strike", DocX.w.NamespaceName)));
  150. break;
  151. case StrikeThrough.doubleStrike:
  152. rPr.Add(new XElement(XName.Get("dstrike", DocX.w.NamespaceName)));
  153. break;
  154. default:
  155. break;
  156. }
  157. switch (script)
  158. {
  159. case Script.none:
  160. break;
  161. default:
  162. rPr.Add(new XElement(XName.Get("vertAlign", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), script.ToString())));
  163. break;
  164. }
  165. if (size.HasValue)
  166. {
  167. rPr.Add(new XElement(XName.Get("sz", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), (size * 2).ToString())));
  168. rPr.Add(new XElement(XName.Get("szCs", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), (size * 2).ToString())));
  169. }
  170. if(fontColor.HasValue)
  171. rPr.Add(new XElement(XName.Get("color", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), fontColor.Value.ToHex())));
  172. switch (highlight)
  173. {
  174. case Highlight.none:
  175. break;
  176. default:
  177. rPr.Add(new XElement(XName.Get("highlight", DocX.w.NamespaceName), new XAttribute(XName.Get("val", DocX.w.NamespaceName), highlight.ToString())));
  178. break;
  179. }
  180. switch (capsStyle)
  181. {
  182. case CapsStyle.none:
  183. break;
  184. default:
  185. rPr.Add(new XElement(XName.Get(capsStyle.ToString(), DocX.w.NamespaceName)));
  186. break;
  187. }
  188. switch (misc)
  189. {
  190. case Misc.none:
  191. break;
  192. case Misc.outlineShadow:
  193. rPr.Add(new XElement(XName.Get("outline", DocX.w.NamespaceName)));
  194. rPr.Add(new XElement(XName.Get("shadow", DocX.w.NamespaceName)));
  195. break;
  196. case Misc.engrave:
  197. rPr.Add(new XElement(XName.Get("imprint", DocX.w.NamespaceName)));
  198. break;
  199. default:
  200. rPr.Add(new XElement(XName.Get(misc.ToString(), DocX.w.NamespaceName)));
  201. break;
  202. }
  203. return rPr;
  204. }
  205. }
  206. /// <summary>
  207. /// This formatting will apply Bold.
  208. /// </summary>
  209. public bool Bold { get { return bold; } set { bold = value;} }
  210. /// <summary>
  211. /// This formatting will apply Italic.
  212. /// </summary>
  213. public bool Italic { get { return italic; } set { italic = value; } }
  214. /// <summary>
  215. /// This formatting will apply StrickThrough.
  216. /// </summary>
  217. public StrikeThrough StrikeThrough { get { return strikethrough; } set { strikethrough = value; } }
  218. /// <summary>
  219. /// The script that this formatting should be, normal, superscript or subscript.
  220. /// </summary>
  221. public Script Script { get { return script; } set { script = value; } }
  222. /// <summary>
  223. /// The Size of this text, must be between 0 and 1638.
  224. /// </summary>
  225. public double? Size
  226. {
  227. get { return size; }
  228. set
  229. {
  230. double? temp = value * 2;
  231. if (temp - (int)temp == 0)
  232. {
  233. if(value > 0 && value < 1639)
  234. size = value;
  235. else
  236. throw new ArgumentException("Size", "Value must be in the range 0 - 1638");
  237. }
  238. else
  239. throw new ArgumentException("Size", "Value must be either a whole or half number, examples: 32, 32.5");
  240. }
  241. }
  242. /// <summary>
  243. /// Percentage scale must be one of the following values 200, 150, 100, 90, 80, 66, 50 or 33.
  244. /// </summary>
  245. public int? PercentageScale
  246. {
  247. get { return percentageScale; }
  248. set
  249. {
  250. if ((new int?[] { 200, 150, 100, 90, 80, 66, 50, 33 }).Contains(value))
  251. percentageScale = value;
  252. else
  253. throw new ArgumentOutOfRangeException("PercentageScale", "Value must be one of the following: 200, 150, 100, 90, 80, 66, 50 or 33");
  254. }
  255. }
  256. /// <summary>
  257. /// The Kerning to apply to this text must be one of the following values 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72.
  258. /// </summary>
  259. public int? Kerning
  260. {
  261. get { return kerning; }
  262. set
  263. {
  264. if(new int?[] {8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72}.Contains(value))
  265. kerning = value;
  266. else
  267. throw new ArgumentOutOfRangeException("Kerning", "Value must be one of the following: 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48 or 72");
  268. }
  269. }
  270. /// <summary>
  271. /// Text position must be in the range (-1585 - 1585).
  272. /// </summary>
  273. public int? Position
  274. {
  275. get { return position; }
  276. set
  277. {
  278. if (value > -1585 && value < 1585)
  279. position = value;
  280. else
  281. throw new ArgumentOutOfRangeException("Position", "Value must be in the range -1585 - 1585");
  282. }
  283. }
  284. /// <summary>
  285. /// Text spacing must be in the range (-1585 - 1585).
  286. /// </summary>
  287. public double? Spacing
  288. {
  289. get { return spacing; }
  290. set
  291. {
  292. double? temp = value * 20;
  293. if (temp - (int)temp == 0)
  294. {
  295. if (value > -1585 && value < 1585)
  296. spacing = value;
  297. else
  298. throw new ArgumentException("Spacing", "Value must be in the range: -1584 - 1584");
  299. }
  300. else
  301. throw new ArgumentException("Spacing", "Value must be either a whole or acurate to one decimal, examples: 32, 32.1, 32.2, 32.9");
  302. }
  303. }
  304. /// <summary>
  305. /// The colour of the text.
  306. /// </summary>
  307. public Color? FontColor { get { return fontColor; } set { fontColor = value; } }
  308. /// <summary>
  309. /// Highlight colour.
  310. /// </summary>
  311. public Highlight Highlight { get { return highlight; } set { highlight = value; } }
  312. /// <summary>
  313. /// The Underline style that this formatting applies.
  314. /// </summary>
  315. public UnderlineStyle UnderlineStyle { get { return underlineStyle; } set { underlineStyle = value; } }
  316. /// <summary>
  317. /// The underline colour.
  318. /// </summary>
  319. public Color? UnderlineColor { get { return underlineColor; } set { underlineColor = value; } }
  320. /// <summary>
  321. /// Misc settings.
  322. /// </summary>
  323. public Misc Misc { get { return misc; } set { misc = value; } }
  324. /// <summary>
  325. /// Is this text hidden or visible.
  326. /// </summary>
  327. public bool Hidden { get { return hidden; } set { hidden = value; } }
  328. /// <summary>
  329. /// Capitalization style.
  330. /// </summary>
  331. public CapsStyle CapsStyle { get { return capsStyle; } set { capsStyle = value; } }
  332. /// <summary>
  333. /// The font familt of this formatting.
  334. /// </summary>
  335. /// <!--
  336. /// Bug found and fixed by krugs525 on August 12 2009.
  337. /// Use TFS compare to see exact code change.
  338. /// -->
  339. public FontFamily FontFamily { get { return fontFamily; } set { fontFamily = value; } }
  340. public int CompareTo(object obj)
  341. {
  342. Formatting other = (Formatting)obj;
  343. if(other.hidden != this.hidden)
  344. return -1;
  345. if(other.bold != this.bold)
  346. return -1;
  347. if(other.italic != this.italic)
  348. return -1;
  349. if(other.strikethrough != this.strikethrough)
  350. return -1;
  351. if(other.script != this.script)
  352. return -1;
  353. if(other.highlight != this.highlight)
  354. return -1;
  355. if(other.size != this.size)
  356. return -1;
  357. if(other.fontColor != this.fontColor)
  358. return -1;
  359. if(other.underlineColor != this.underlineColor)
  360. return -1;
  361. if(other.underlineStyle != this.underlineStyle)
  362. return -1;
  363. if(other.misc != this.misc)
  364. return -1;
  365. if(other.capsStyle != this.capsStyle)
  366. return -1;
  367. if(other.fontFamily != this.fontFamily)
  368. return -1;
  369. if(other.percentageScale != this.percentageScale)
  370. return -1;
  371. if(other.kerning != this.kerning)
  372. return -1;
  373. if(other.position != this.position)
  374. return -1;
  375. if(other.spacing != this.spacing)
  376. return -1;
  377. if (!other.language.Equals(this.language))
  378. return -1;
  379. return 0;
  380. }
  381. }
  382. }