FontInfo.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
  21. //
  22. // Authors:
  23. // Peter Dennis Bartok ([email protected])
  24. //
  25. //
  26. using System.ComponentModel;
  27. using System.Security.Permissions;
  28. namespace System.Web.UI.WebControls {
  29. // CAS
  30. [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  31. // attributes
  32. [TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
  33. public sealed class FontInfo
  34. {
  35. [Flags]
  36. internal enum FontStyles
  37. {
  38. None = 0,
  39. Bold = 0x0001,
  40. Italic = 0x0002,
  41. Names = 0x0004,
  42. Overline = 0x0008,
  43. Size = 0x0010,
  44. Strikeout = 0x0020,
  45. Underline = 0x0040
  46. }
  47. #region Fields
  48. private static string[] empty_names = new string[0];
  49. private FontStyles fontstyles;
  50. private StateBag bag;
  51. #endregion // Fields
  52. #region Constructors
  53. internal FontInfo(Style owner)
  54. {
  55. this.bag = owner.ViewState;
  56. }
  57. #endregion // Constructors
  58. #region Public Instance Properties
  59. #if ONLY_1_1
  60. [Bindable(true)]
  61. #endif
  62. [DefaultValue(false)]
  63. [NotifyParentProperty(true)]
  64. [WebSysDescription ("")]
  65. [WebCategory ("Font")]
  66. public bool Bold
  67. {
  68. get
  69. {
  70. if ((fontstyles & FontStyles.Bold) == 0)
  71. {
  72. return false;
  73. }
  74. return bag.GetBool("Font_Bold", false);
  75. }
  76. set
  77. {
  78. fontstyles |= FontStyles.Bold;
  79. bag["Font_Bold"] = value;
  80. }
  81. }
  82. #if ONLY_1_1
  83. [Bindable(true)]
  84. #endif
  85. [DefaultValue(false)]
  86. [NotifyParentProperty(true)]
  87. [WebSysDescription ("")]
  88. [WebCategory ("Font")]
  89. public bool Italic
  90. {
  91. get
  92. {
  93. if ((fontstyles & FontStyles.Italic) == 0)
  94. {
  95. return false;
  96. }
  97. return bag.GetBool("Font_Italic", false);
  98. }
  99. set
  100. {
  101. fontstyles |= FontStyles.Italic;
  102. bag["Font_Italic"] = value;
  103. }
  104. }
  105. #if NET_2_0
  106. [RefreshProperties (RefreshProperties.Repaint)]
  107. #else
  108. [Bindable(true)]
  109. #endif
  110. [DefaultValue("")]
  111. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  112. [Editor("System.Drawing.Design.FontNameEditor, " + Consts.AssemblySystem_Drawing_Design, typeof(System.Drawing.Design.UITypeEditor))]
  113. [NotifyParentProperty(true)]
  114. [TypeConverter (typeof(System.Drawing.FontConverter.FontNameConverter))]
  115. [WebSysDescription ("")]
  116. [WebCategory ("Font")]
  117. public string Name
  118. {
  119. get
  120. {
  121. string [] names = Names;
  122. if (names.Length == 0)
  123. return string.Empty;
  124. return names[0];
  125. }
  126. set
  127. {
  128. // Seems to be a special case in MS, removing the names from the bag when Name is set to empty,
  129. // but not when setting Names to an empty array
  130. if (value == string.Empty) {
  131. Names = null;
  132. return;
  133. }
  134. if (value == null) {
  135. throw new ArgumentNullException("value", "Font name cannot be null");
  136. }
  137. Names = new string[1] { value };
  138. }
  139. }
  140. #if NET_2_0
  141. [RefreshProperties (RefreshProperties.Repaint)]
  142. #endif
  143. [Editor("System.Windows.Forms.Design.StringArrayEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
  144. [NotifyParentProperty(true)]
  145. [TypeConverter(typeof(System.Web.UI.WebControls.FontNamesConverter))]
  146. [WebSysDescription ("")]
  147. [WebCategory ("Font")]
  148. public string[] Names
  149. {
  150. get
  151. {
  152. string[] ret;
  153. if ((fontstyles & FontStyles.Names) == 0)
  154. {
  155. return FontInfo.empty_names;
  156. }
  157. ret = (string[])bag["Font_Names"];
  158. if (ret != null) {
  159. return ret;
  160. }
  161. return FontInfo.empty_names;
  162. }
  163. set
  164. {
  165. if (value == null) {
  166. fontstyles &= ~FontStyles.Names;
  167. bag.Remove ("Font_Names");
  168. }
  169. else {
  170. fontstyles |= FontStyles.Names;
  171. bag ["Font_Names"] = value;
  172. }
  173. }
  174. }
  175. #if ONLY_1_1
  176. [Bindable(true)]
  177. #endif
  178. [DefaultValue(false)]
  179. [NotifyParentProperty(true)]
  180. [WebSysDescription ("")]
  181. [WebCategory ("Font")]
  182. public bool Overline
  183. {
  184. get
  185. {
  186. if ((fontstyles & FontStyles.Overline) == 0)
  187. {
  188. return false;
  189. }
  190. return bag.GetBool("Font_Overline", false);
  191. }
  192. set
  193. {
  194. fontstyles |= FontStyles.Overline;
  195. bag["Font_Overline"] = value;
  196. }
  197. }
  198. #if NET_2_0
  199. [RefreshProperties (RefreshProperties.Repaint)]
  200. #else
  201. [Bindable(true)]
  202. #endif
  203. [DefaultValue(typeof (FontUnit), "")]
  204. [NotifyParentProperty(true)]
  205. [WebSysDescription ("")]
  206. [WebCategory ("Font")]
  207. public FontUnit Size
  208. {
  209. get
  210. {
  211. if ((fontstyles & FontStyles.Size) == 0)
  212. {
  213. return FontUnit.Empty;
  214. }
  215. return (FontUnit)bag["Font_Size"];
  216. }
  217. set
  218. {
  219. if (value.Unit.Value < 0)
  220. {
  221. throw new ArgumentOutOfRangeException("Value", value.Unit.Value, "Font size cannot be negative");
  222. }
  223. fontstyles |= FontStyles.Size;
  224. bag["Font_Size"] = value;
  225. }
  226. }
  227. #if ONLY_1_1
  228. [Bindable(true)]
  229. #endif
  230. [DefaultValue(false)]
  231. [NotifyParentProperty(true)]
  232. [WebSysDescription ("")]
  233. [WebCategory ("Font")]
  234. public bool Strikeout
  235. {
  236. get
  237. {
  238. if ((fontstyles & FontStyles.Strikeout) == 0)
  239. {
  240. return false;
  241. }
  242. return bag.GetBool("Font_Strikeout", false);
  243. }
  244. set
  245. {
  246. fontstyles |= FontStyles.Strikeout;
  247. bag["Font_Strikeout"] = value;
  248. }
  249. }
  250. #if ONLY_1_1
  251. [Bindable(true)]
  252. #endif
  253. [DefaultValue(false)]
  254. [NotifyParentProperty(true)]
  255. [WebSysDescription ("")]
  256. [WebCategory ("Font")]
  257. public bool Underline
  258. {
  259. get
  260. {
  261. if ((fontstyles & FontStyles.Underline) == 0)
  262. {
  263. return false;
  264. }
  265. return bag.GetBool("Font_Underline", false);
  266. }
  267. set
  268. {
  269. fontstyles |= FontStyles.Underline;
  270. bag["Font_Underline"] = value;
  271. }
  272. }
  273. #endregion // Public Instance Properties
  274. #region Public Instance Methods
  275. public void CopyFrom(FontInfo f)
  276. {
  277. //Methods CopyFrom and MergeWith behave differently between 1.1 and 2.0
  278. if (f == null || f.IsEmpty)
  279. return;
  280. if (f == this)
  281. return;
  282. #if NET_2_0
  283. // MS stores the property in the bag if it's value is false
  284. if ((f.fontstyles & FontStyles.Bold) != 0) {
  285. this.Bold = f.Bold;
  286. }
  287. if ((f.fontstyles & FontStyles.Italic) != 0) {
  288. this.Italic = f.Italic;
  289. }
  290. // MS seems to have some weird behaviour, even if f's Name has been set to String.Empty we still get an empty array
  291. this.Names = f.Names;
  292. if ((f.fontstyles & FontStyles.Overline) != 0) {
  293. this.Overline = f.Overline;
  294. }
  295. if ((f.fontstyles & FontStyles.Size) != 0) {
  296. this.Size = f.Size;
  297. }
  298. if ((f.fontstyles & FontStyles.Strikeout) != 0) {
  299. this.Strikeout = f.Strikeout;
  300. }
  301. if ((f.fontstyles & FontStyles.Underline) != 0) {
  302. this.Underline = f.Underline;
  303. }
  304. #else
  305. // MS does not store the property in the bag if it's value is false
  306. if (((f.fontstyles & FontStyles.Bold) != 0) && f.Bold)
  307. {
  308. this.Bold = true;
  309. }
  310. if (((f.fontstyles & FontStyles.Italic) != 0) && f.Italic)
  311. {
  312. this.Italic = true;
  313. }
  314. // MS seems to have some weird behaviour, even if f's Name has been set to String.Empty we still get an empty array
  315. this.Names = f.Names;
  316. if (((f.fontstyles & FontStyles.Overline) != 0) && f.Overline)
  317. {
  318. this.Overline = true;
  319. }
  320. if (((f.fontstyles & FontStyles.Size) != 0) && (f.Size != FontUnit.Empty))
  321. {
  322. this.Size = f.Size;
  323. }
  324. if (((f.fontstyles & FontStyles.Strikeout) != 0) && f.Strikeout)
  325. {
  326. this.Strikeout = true;
  327. }
  328. if (((f.fontstyles & FontStyles.Underline) != 0) && f.Underline)
  329. {
  330. this.Underline = true;
  331. }
  332. #endif
  333. }
  334. public void MergeWith(FontInfo f)
  335. {
  336. //Methods CopyFrom and MergeWith behave differently between 1.1 and 2.0
  337. #if NET_2_0
  338. if (((fontstyles & FontStyles.Bold) == 0) && ((f.fontstyles & FontStyles.Bold) != 0)) {
  339. this.Bold = f.Bold;
  340. }
  341. if (((fontstyles & FontStyles.Italic) == 0) && ((f.fontstyles & FontStyles.Italic) != 0)) {
  342. this.Italic = f.Italic;
  343. }
  344. if (((fontstyles & FontStyles.Names) == 0) && ((f.fontstyles & FontStyles.Names) != 0)) {
  345. this.Names = f.Names;
  346. }
  347. if (((fontstyles & FontStyles.Overline) == 0) && ((f.fontstyles & FontStyles.Overline) != 0)) {
  348. this.Overline = f.Overline;
  349. }
  350. if (((fontstyles & FontStyles.Size) == 0) && ((f.fontstyles & FontStyles.Size) != 0)) {
  351. this.Size = f.Size;
  352. }
  353. if (((fontstyles & FontStyles.Strikeout) == 0) && ((f.fontstyles & FontStyles.Strikeout) != 0)) {
  354. this.Strikeout = f.Strikeout;
  355. }
  356. if (((fontstyles & FontStyles.Underline) == 0) && ((f.fontstyles & FontStyles.Underline) != 0)) {
  357. this.Underline = f.Underline;
  358. }
  359. #else
  360. if (((fontstyles & FontStyles.Bold) == 0) && ((f.fontstyles & FontStyles.Bold) != 0) && f.Bold)
  361. {
  362. this.Bold = true;
  363. }
  364. if (((fontstyles & FontStyles.Italic) == 0) && ((f.fontstyles & FontStyles.Italic) != 0) && f.Italic)
  365. {
  366. this.Italic = true;
  367. }
  368. if (((fontstyles & FontStyles.Names) == 0) && ((f.fontstyles & FontStyles.Names) != 0))
  369. {
  370. this.Names = f.Names;
  371. }
  372. if (((fontstyles & FontStyles.Overline) == 0) && ((f.fontstyles & FontStyles.Overline) != 0) && f.Overline)
  373. {
  374. this.Overline = true;
  375. }
  376. if (((fontstyles & FontStyles.Size) == 0) && ((f.fontstyles & FontStyles.Size) != 0) && (f.Size != FontUnit.Empty))
  377. {
  378. this.Size = f.Size;
  379. }
  380. if (((fontstyles & FontStyles.Strikeout) == 0) && ((f.fontstyles & FontStyles.Strikeout) != 0) && f.Strikeout)
  381. {
  382. this.Strikeout = true;
  383. }
  384. if (((fontstyles & FontStyles.Underline) == 0) && ((f.fontstyles & FontStyles.Underline) != 0) && f.Underline)
  385. {
  386. this.Underline = true;
  387. }
  388. #endif
  389. }
  390. public bool ShouldSerializeNames()
  391. {
  392. return (Names.Length != 0);
  393. }
  394. public override string ToString()
  395. {
  396. if (this.Names.Length == 0)
  397. {
  398. return this.Size.ToString();
  399. }
  400. return this.Name + ", " + this.Size.ToString();
  401. }
  402. #if NET_2_0
  403. public void ClearDefaults () {
  404. Reset ();
  405. }
  406. #endif
  407. #endregion // Public Instance Methods
  408. #region Private Methods
  409. internal void Reset()
  410. {
  411. bag.Remove("Font_Bold");
  412. bag.Remove("Font_Italic");
  413. bag.Remove("Font_Names");
  414. bag.Remove("Font_Overline");
  415. bag.Remove("Font_Size");
  416. bag.Remove("Font_Strikeout");
  417. bag.Remove("Font_Underline");
  418. fontstyles = FontStyles.None;
  419. }
  420. internal void LoadViewState() {
  421. fontstyles = FontStyles.None;
  422. if (bag["Font_Bold"] != null)
  423. {
  424. fontstyles |= FontStyles.Bold;
  425. }
  426. if (bag["Font_Italic"] != null)
  427. {
  428. fontstyles |= FontStyles.Italic;
  429. }
  430. if (bag["Font_Names"] != null)
  431. {
  432. fontstyles |= FontStyles.Names;
  433. }
  434. if (bag["Font_Overline"] != null)
  435. {
  436. fontstyles |= FontStyles.Overline;
  437. }
  438. if (bag["Font_Size"] != null)
  439. {
  440. fontstyles |= FontStyles.Size;
  441. }
  442. if (bag["Font_Strikeout"] != null)
  443. {
  444. fontstyles |= FontStyles.Strikeout;
  445. }
  446. if (bag["Font_Underline"] != null)
  447. {
  448. fontstyles |= FontStyles.Underline;
  449. }
  450. }
  451. #if NET_2_0
  452. internal void FillStyleAttributes (CssStyleCollection attributes, bool alwaysRenderTextDecoration) {
  453. if (IsEmpty) {
  454. if(alwaysRenderTextDecoration)
  455. attributes.Add (HtmlTextWriterStyle.TextDecoration, "none");
  456. return;
  457. }
  458. string s;
  459. // Fonts are a bit weird
  460. s = String.Join (",", Names);
  461. if (s.Length > 0) {
  462. attributes.Add (HtmlTextWriterStyle.FontFamily, s);
  463. }
  464. if ((fontstyles & FontStyles.Bold) != 0) {
  465. attributes.Add (HtmlTextWriterStyle.FontWeight, Bold ? "bold" : "normal");
  466. }
  467. if ((fontstyles & FontStyles.Italic) != 0) {
  468. attributes.Add (HtmlTextWriterStyle.FontStyle, Italic ? "italic" : "normal");
  469. }
  470. if (!Size.IsEmpty) {
  471. attributes.Add (HtmlTextWriterStyle.FontSize, Size.ToString ());
  472. }
  473. // These styles are munged into a attribute decoration
  474. s = string.Empty;
  475. bool hasTextDecoration = false;
  476. if ((fontstyles & FontStyles.Overline) != 0) {
  477. if (Overline)
  478. s += "overline ";
  479. hasTextDecoration = true;
  480. }
  481. if ((fontstyles & FontStyles.Strikeout) != 0) {
  482. if (Strikeout)
  483. s += "line-through ";
  484. hasTextDecoration = true;
  485. }
  486. if ((fontstyles & FontStyles.Underline) != 0) {
  487. if (Underline)
  488. s += "underline ";
  489. hasTextDecoration = true;
  490. }
  491. s = (s.Length > 0) ? s.Trim () : (alwaysRenderTextDecoration || hasTextDecoration) ? "none" : "";
  492. if (s.Length > 0)
  493. attributes.Add (HtmlTextWriterStyle.TextDecoration, s);
  494. }
  495. #endif
  496. #endregion // Private Methods
  497. internal bool IsEmpty {
  498. get {
  499. return fontstyles == FontStyles.None;
  500. }
  501. }
  502. }
  503. }