Merge pull request #2832 from razzfazz/handle_eintr
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / FontInfo.cs
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-2010 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Peter Dennis Bartok     (pbartok@novell.com)
24 //
25 //
26
27 using System.ComponentModel;
28 using System.Security.Permissions;
29
30 namespace System.Web.UI.WebControls
31 {
32         // CAS
33         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
34         // attributes
35         [TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
36         public sealed class FontInfo 
37         {
38                 #region Fields
39                 static string[] empty_names = new string[0];
40                 StateBag bag;
41                 Style _owner;
42                 #endregion      // Fields
43
44                 #region Constructors
45                 internal FontInfo(Style owner) 
46                 {
47                         _owner = owner;
48                         this.bag = owner.ViewState;
49                 }
50                 #endregion      // Constructors
51
52                 #region Public Instance Properties
53                 [DefaultValue(false)]
54                 [NotifyParentProperty(true)]
55                 [WebSysDescription ("")]
56                 [WebCategory ("Font")]
57                 public bool Bold {
58                         get  {
59                                 if (!_owner.CheckBit((int)Style.Styles.FontBold))
60                                         return false;
61
62                                 return bag.GetBool("Font_Bold", false);
63                         }
64
65                         set {
66                                 bag["Font_Bold"] = value;
67                                 _owner.SetBit ((int) Style.Styles.FontBold);
68                         }
69                 }
70
71                 [DefaultValue(false)]
72                 [NotifyParentProperty(true)]
73                 [WebSysDescription ("")]
74                 [WebCategory ("Font")]
75                 public bool Italic  {
76                         get {
77                                 if (!_owner.CheckBit ((int) Style.Styles.FontItalic))
78                                         return false;
79
80                                 return bag.GetBool("Font_Italic", false);
81                         }
82
83                         set {
84                                 bag["Font_Italic"] = value;
85                                 _owner.SetBit ((int) Style.Styles.FontItalic);
86                         }
87                 }
88
89                 [RefreshProperties (RefreshProperties.Repaint)]
90                 [DefaultValue("")]
91                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
92                 [Editor("System.Drawing.Design.FontNameEditor, " + Consts.AssemblySystem_Drawing_Design, typeof(System.Drawing.Design.UITypeEditor))]
93                 [NotifyParentProperty(true)]
94                 [TypeConverter (typeof(System.Drawing.FontConverter.FontNameConverter))]
95                 [WebSysDescription ("")]
96                 [WebCategory ("Font")]
97                 public string Name {
98                         get {
99                                 string [] names = Names;
100
101                                 if (names.Length == 0)
102                                         return string.Empty;
103
104                                 return names[0];
105                         }
106
107                         set {
108                                 // Seems to be a special case in MS, removing the names from the bag when Name is set to empty, 
109                                 // but not when setting Names to an empty array
110                                 if (value == string.Empty) {
111                                         Names = null;
112                                         return;
113                                 }
114
115                                 if (value == null)
116                                         throw new ArgumentNullException("value", "Font name cannot be null");
117                                 Names = new string[1] { value };
118                         }
119                 }
120
121                 [RefreshProperties (RefreshProperties.Repaint)]
122                 [Editor("System.Windows.Forms.Design.StringArrayEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
123                 [NotifyParentProperty(true)]
124                 [TypeConverter(typeof(System.Web.UI.WebControls.FontNamesConverter))]
125                 [WebSysDescription ("")]
126                 [WebCategory ("Font")]
127                 public string[] Names {
128                         get  {
129                                 string[] ret;
130
131                                 if (!_owner.CheckBit ((int) Style.Styles.FontNames))
132                                         return FontInfo.empty_names;
133
134                                 ret = (string[])bag["Font_Names"];
135
136                                 if (ret != null)
137                                         return ret;
138                                 
139                                 return FontInfo.empty_names;
140                         }
141
142                         set {
143                                 if (value == null) {
144                                         bag.Remove ("Font_Names");
145                                         _owner.RemoveBit ((int) Style.Styles.FontNames);
146                                 } else {
147                                         bag ["Font_Names"] = value;
148                                         _owner.SetBit ((int) Style.Styles.FontNames);
149                                 }
150                         }
151                 }
152
153                 [DefaultValue(false)]
154                 [NotifyParentProperty(true)]
155                 [WebSysDescription ("")]
156                 [WebCategory ("Font")]
157                 public bool Overline {
158                         get {
159                                 if (!_owner.CheckBit ((int) Style.Styles.FontOverline)) 
160                                         return false;
161
162                                 return bag.GetBool("Font_Overline", false);
163                         }
164
165                         set {
166                                 bag["Font_Overline"] = value;
167                                 _owner.SetBit ((int) Style.Styles.FontOverline);
168                         }
169                 }
170
171                 [RefreshProperties (RefreshProperties.Repaint)]
172                 [DefaultValue(typeof (FontUnit), "")]
173                 [NotifyParentProperty(true)]
174                 [WebSysDescription ("")]
175                 [WebCategory ("Font")]
176                 public FontUnit Size {
177                         get {
178                                 if (!_owner.CheckBit ((int) Style.Styles.FontSize)) 
179                                         return FontUnit.Empty;
180
181                                 return (FontUnit)bag["Font_Size"];
182                         }
183
184                         set {
185                                 if (value.Unit.Value < 0)
186                                         throw new ArgumentOutOfRangeException("Value", value.Unit.Value, "Font size cannot be negative");
187                                 
188                                 bag["Font_Size"] = value;
189                                 _owner.SetBit ((int) Style.Styles.FontSize);
190                         }
191                 }
192
193                 [DefaultValue(false)]
194                 [NotifyParentProperty(true)]
195                 [WebSysDescription ("")]
196                 [WebCategory ("Font")]
197                 public bool Strikeout {
198                         get  {
199                                 if (!_owner.CheckBit ((int) Style.Styles.FontStrikeout))
200                                         return false;
201
202                                 return bag.GetBool("Font_Strikeout", false);
203                         }
204
205                         set {
206                                 bag["Font_Strikeout"] = value;
207                                 _owner.SetBit ((int) Style.Styles.FontStrikeout);
208                         }
209                 }
210
211                 [DefaultValue(false)]
212                 [NotifyParentProperty(true)]
213                 [WebSysDescription ("")]
214                 [WebCategory ("Font")]
215                 public bool Underline {
216                         get  {
217                                 if (!_owner.CheckBit ((int) Style.Styles.FontUnderline))
218                                         return false;
219
220                                 return bag.GetBool("Font_Underline", false);
221                         }
222
223                         set {
224                                 bag["Font_Underline"] = value;
225                                 _owner.SetBit ((int) Style.Styles.FontUnderline);
226                         }
227                 }
228                 #endregion      // Public Instance Properties
229
230                 #region Public Instance Methods
231                 public void CopyFrom (FontInfo f) 
232                 {
233                         if (f == null || f.IsEmpty)
234                                 return;
235
236                         if (f == this)
237                                 return;
238
239                         // MS stores the property in the bag if it's value is false
240                         if (f._owner.CheckBit((int) Style.Styles.FontBold))
241                                 this.Bold = f.Bold;
242
243                         if (f._owner.CheckBit ((int) Style.Styles.FontItalic))
244                                 this.Italic = f.Italic;
245
246                         // MS seems to have some weird behaviour, even if f's Name has been set to String.Empty we still get an empty array
247                         this.Names = f.Names;
248
249                         if (f._owner.CheckBit ((int) Style.Styles.FontOverline))
250                                 this.Overline = f.Overline;
251
252                         if (f._owner.CheckBit ((int) Style.Styles.FontSize))
253                                 this.Size = f.Size;
254
255                         if (f._owner.CheckBit ((int) Style.Styles.FontStrikeout))
256                                 this.Strikeout = f.Strikeout;
257
258                         if (f._owner.CheckBit ((int) Style.Styles.FontUnderline))
259                                 this.Underline = f.Underline;
260                 }
261
262                 public void MergeWith (FontInfo f) 
263                 {
264                         if (!_owner.CheckBit ((int) Style.Styles.FontBold) && f._owner.CheckBit ((int) Style.Styles.FontBold))
265                                 this.Bold = f.Bold;
266
267                         if (!_owner.CheckBit ((int) Style.Styles.FontItalic) && f._owner.CheckBit ((int) Style.Styles.FontItalic))
268                                 this.Italic = f.Italic;
269
270                         if (!_owner.CheckBit ((int) Style.Styles.FontNames) && f._owner.CheckBit ((int) Style.Styles.FontNames))
271                                 this.Names = f.Names;
272
273                         if (!_owner.CheckBit ((int) Style.Styles.FontOverline) && f._owner.CheckBit ((int) Style.Styles.FontOverline))
274                                 this.Overline = f.Overline;
275
276                         if (!_owner.CheckBit ((int) Style.Styles.FontSize) && f._owner.CheckBit ((int) Style.Styles.FontSize))
277                                 this.Size = f.Size;
278
279                         if (!_owner.CheckBit ((int) Style.Styles.FontStrikeout) && f._owner.CheckBit ((int) Style.Styles.FontStrikeout))
280                                 this.Strikeout = f.Strikeout;
281
282                         if (!_owner.CheckBit ((int) Style.Styles.FontUnderline) && f._owner.CheckBit ((int) Style.Styles.FontUnderline))
283                                 this.Underline = f.Underline;
284                 }
285
286                 public bool ShouldSerializeNames () 
287                 {
288                         return (Names.Length != 0);
289                 }
290
291                 public override string ToString () 
292                 {
293                         if (this.Names.Length == 0)
294                                 return this.Size.ToString();
295
296                         return this.Name + ", " + this.Size.ToString();
297                 }
298
299                 public void ClearDefaults ()
300                 {
301                         Reset ();
302                 }
303
304                 #endregion      // Public Instance Methods
305
306                 #region Private Methods
307                 internal void Reset() 
308                 {
309                         bag.Remove("Font_Bold");
310                         bag.Remove("Font_Italic");
311                         bag.Remove("Font_Names");
312                         bag.Remove("Font_Overline");
313                         bag.Remove("Font_Size");
314                         bag.Remove("Font_Strikeout");
315                         bag.Remove("Font_Underline");
316                         _owner.RemoveBit ((int) Style.Styles.FontAll);
317                 }
318
319                 internal void FillStyleAttributes (CssStyleCollection attributes, bool alwaysRenderTextDecoration)
320                 {
321                         if (IsEmpty) {
322                                 if(alwaysRenderTextDecoration)
323                                         attributes.Add (HtmlTextWriterStyle.TextDecoration, "none");
324                                 return;
325                         }
326
327                         string s;
328                         // Fonts are a bit weird
329                         s = String.Join (",", Names);
330                         if (s.Length > 0)
331                                 attributes.Add (HtmlTextWriterStyle.FontFamily, s);
332
333                         if (_owner.CheckBit ((int) Style.Styles.FontBold))
334                                 attributes.Add (HtmlTextWriterStyle.FontWeight, Bold ? "bold" : "normal");
335
336                         if (_owner.CheckBit ((int) Style.Styles.FontItalic))
337                                 attributes.Add (HtmlTextWriterStyle.FontStyle, Italic ? "italic" : "normal");
338
339                         if (!Size.IsEmpty)
340                                 attributes.Add (HtmlTextWriterStyle.FontSize, Size.ToString ());
341
342                         // These styles are munged into a attribute decoration
343                         s = String.Empty;
344                         bool hasTextDecoration = false;
345
346                         if (_owner.CheckBit ((int) Style.Styles.FontOverline)) {
347                                 if (Overline)
348                                         s += "overline ";
349                                 hasTextDecoration = true;
350                         }
351
352                         if (_owner.CheckBit ((int) Style.Styles.FontStrikeout)) {
353                                 if (Strikeout)
354                                         s += "line-through ";
355                                 hasTextDecoration = true;
356                         }
357
358                         if (_owner.CheckBit ((int) Style.Styles.FontUnderline)) {
359                                 if (Underline)
360                                         s += "underline ";
361                                 hasTextDecoration = true;
362                         }
363
364                         s = (s.Length > 0) ? s.Trim () : (alwaysRenderTextDecoration || hasTextDecoration) ? "none" : String.Empty;
365                         if (s.Length > 0)
366                                 attributes.Add (HtmlTextWriterStyle.TextDecoration, s);
367                 }
368                 #endregion      // Private Methods
369
370
371                 bool IsEmpty {
372                         get { return !_owner.CheckBit ((int) Style.Styles.FontAll); }
373                 }
374         }
375 }