Flush (work in progress)
[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 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 #if ONLY_1_1
54                 [Bindable(true)]
55 #endif
56                 [DefaultValue(false)]
57                 [NotifyParentProperty(true)]
58                 [WebSysDescription ("")]
59                 [WebCategory ("Font")]
60                 public bool Bold 
61                 {
62                         get 
63                         {
64                                 if (!_owner.CheckBit((int)Style.Styles.FontBold)) 
65                                 {
66                                         return false;
67                                 }
68
69                                 return bag.GetBool("Font_Bold", false);
70                         }
71
72                         set 
73                         {
74                                 bag["Font_Bold"] = value;
75                                 _owner.SetBit ((int) Style.Styles.FontBold);
76                         }
77                 }
78
79 #if ONLY_1_1
80                 [Bindable(true)]
81 #endif
82                 [DefaultValue(false)]
83                 [NotifyParentProperty(true)]
84                 [WebSysDescription ("")]
85                 [WebCategory ("Font")]
86                 public bool Italic 
87                 {
88                         get 
89                         {
90                                 if (!_owner.CheckBit ((int) Style.Styles.FontItalic))
91                                 {
92                                         return false;
93                                 }
94
95                                 return bag.GetBool("Font_Italic", false);
96                         }
97
98                         set 
99                         {
100                                 bag["Font_Italic"] = value;
101                                 _owner.SetBit ((int) Style.Styles.FontItalic);
102                         }
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
123                                 if (names.Length == 0)
124                                         return string.Empty;
125
126                                 return names[0];
127                         }
128
129                         set 
130                         {
131                                 // Seems to be a special case in MS, removing the names from the bag when Name is set to empty, 
132                                 // but not when setting Names to an empty array
133                                 if (value == string.Empty) {
134                                         Names = null;
135                                         return;
136                                 }
137
138                                 if (value == null) {
139                                         throw new ArgumentNullException("value", "Font name cannot be null");
140                                 }
141                                 Names = new string[1] { value };
142                         }
143                 }
144
145 #if NET_2_0
146                 [RefreshProperties (RefreshProperties.Repaint)]
147 #endif
148                 [Editor("System.Windows.Forms.Design.StringArrayEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
149                 [NotifyParentProperty(true)]
150                 [TypeConverter(typeof(System.Web.UI.WebControls.FontNamesConverter))]
151                 [WebSysDescription ("")]
152                 [WebCategory ("Font")]
153                 public string[] Names 
154                 {
155                         get 
156                         {
157                                 string[] ret;
158
159                                 if (!_owner.CheckBit ((int) Style.Styles.FontNames)) 
160                                 {
161                                         return FontInfo.empty_names;
162                                 }
163
164                                 ret = (string[])bag["Font_Names"];
165
166                                 if (ret != null) {
167                                         return ret;
168                                 }
169                                 return FontInfo.empty_names;
170                         }
171
172                         set 
173                         {
174                                 if (value == null) {
175                                         bag.Remove ("Font_Names");
176                                         _owner.RemoveBit ((int) Style.Styles.FontNames);
177                                 }
178                                 else {
179                                         bag ["Font_Names"] = value;
180                                         _owner.SetBit ((int) Style.Styles.FontNames);
181                                 }
182                         }
183                 }
184
185 #if ONLY_1_1
186                 [Bindable(true)]
187 #endif
188                 [DefaultValue(false)]
189                 [NotifyParentProperty(true)]
190                 [WebSysDescription ("")]
191                 [WebCategory ("Font")]
192                 public bool Overline 
193                 {
194                         get 
195                         {
196                                 if (!_owner.CheckBit ((int) Style.Styles.FontOverline)) 
197                                 {
198                                         return false;
199                                 }
200
201                                 return bag.GetBool("Font_Overline", false);
202                         }
203
204                         set 
205                         {
206                                 bag["Font_Overline"] = value;
207                                 _owner.SetBit ((int) Style.Styles.FontOverline);
208                         }
209                 }
210
211 #if NET_2_0
212                 [RefreshProperties (RefreshProperties.Repaint)]
213 #else
214                 [Bindable(true)]
215 #endif
216                 [DefaultValue(typeof (FontUnit), "")]
217                 [NotifyParentProperty(true)]
218                 [WebSysDescription ("")]
219                 [WebCategory ("Font")]
220                 public FontUnit Size 
221                 {
222                         get 
223                         {
224                                 if (!_owner.CheckBit ((int) Style.Styles.FontSize)) 
225                                 {
226                                         return FontUnit.Empty;
227                                 }
228
229                                 return (FontUnit)bag["Font_Size"];
230                         }
231
232                         set 
233                         {
234                                 if (value.Unit.Value < 0) 
235                                 {
236                                         throw new ArgumentOutOfRangeException("Value", value.Unit.Value, "Font size cannot be negative");
237                                 }
238                                 bag["Font_Size"] = value;
239                                 _owner.SetBit ((int) Style.Styles.FontSize);
240                         }
241                 }
242
243 #if ONLY_1_1
244                 [Bindable(true)]
245 #endif
246                 [DefaultValue(false)]
247                 [NotifyParentProperty(true)]
248                 [WebSysDescription ("")]
249                 [WebCategory ("Font")]
250                 public bool Strikeout 
251                 {
252                         get 
253                         {
254                                 if (!_owner.CheckBit ((int) Style.Styles.FontStrikeout)) 
255                                 {
256                                         return false;
257                                 }
258
259                                 return bag.GetBool("Font_Strikeout", false);
260                         }
261
262                         set 
263                         {
264                                 bag["Font_Strikeout"] = value;
265                                 _owner.SetBit ((int) Style.Styles.FontStrikeout);
266                         }
267                 }
268
269 #if ONLY_1_1
270                 [Bindable(true)]
271 #endif
272                 [DefaultValue(false)]
273                 [NotifyParentProperty(true)]
274                 [WebSysDescription ("")]
275                 [WebCategory ("Font")]
276                 public bool Underline 
277                 {
278                         get 
279                         {
280                                 if (!_owner.CheckBit ((int) Style.Styles.FontUnderline)) 
281                                 {
282                                         return false;
283                                 }
284
285                                 return bag.GetBool("Font_Underline", false);
286                         }
287
288                         set 
289                         {
290                                 bag["Font_Underline"] = value;
291                                 _owner.SetBit ((int) Style.Styles.FontUnderline);
292                         }
293                 }
294                 #endregion      // Public Instance Properties
295
296                 #region Public Instance Methods
297                 public void CopyFrom(FontInfo f) 
298                 {
299                         //Methods CopyFrom and MergeWith behave differently between 1.1 and 2.0
300                         if (f == null || f.IsEmpty)
301                                 return;
302
303                         if (f == this)
304                                 return;
305
306 #if NET_2_0
307                         // MS stores the property in the bag if it's value is false
308                         if (f._owner.CheckBit((int) Style.Styles.FontBold)) {
309                                 this.Bold = f.Bold;
310                         }
311
312                         if (f._owner.CheckBit ((int) Style.Styles.FontItalic)) {
313                                 this.Italic = f.Italic;
314                         }
315
316                         // MS seems to have some weird behaviour, even if f's Name has been set to String.Empty we still get an empty array
317                         this.Names = f.Names;
318
319                         if (f._owner.CheckBit ((int) Style.Styles.FontOverline)) {
320                                 this.Overline = f.Overline;
321                         }
322
323                         if (f._owner.CheckBit ((int) Style.Styles.FontSize)) {
324                                 this.Size = f.Size;
325                         }
326
327                         if (f._owner.CheckBit ((int) Style.Styles.FontStrikeout)) {
328                                 this.Strikeout = f.Strikeout;
329                         }
330
331                         if (f._owner.CheckBit ((int) Style.Styles.FontUnderline)) {
332                                 this.Underline = f.Underline;
333                         }
334 #else
335                         // MS does not store the property in the bag if it's value is false
336                         if ((f._owner.CheckBit ((int) Style.Styles.FontBold)) && f.Bold) 
337                         {
338                                 this.Bold = true;
339                         }
340
341                         if ((f._owner.CheckBit ((int) Style.Styles.FontItalic)) && f.Italic) 
342                         {
343                                 this.Italic = true;
344                         }
345
346                         // MS seems to have some weird behaviour, even if f's Name has been set to String.Empty we still get an empty array
347                         this.Names = f.Names;
348
349                         if ((f._owner.CheckBit ((int) Style.Styles.FontOverline)) && f.Overline) 
350                         {
351                                 this.Overline = true;
352                         }
353
354                         if ((f._owner.CheckBit ((int) Style.Styles.FontSize)) && (f.Size != FontUnit.Empty)) 
355                         {
356                                 this.Size = f.Size;
357                         }
358
359                         if ((f._owner.CheckBit ((int) Style.Styles.FontStrikeout)) && f.Strikeout) 
360                         {
361                                 this.Strikeout = true;
362                         }
363
364                         if ((f._owner.CheckBit ((int) Style.Styles.FontUnderline)) && f.Underline) 
365                         {
366                                 this.Underline = true;
367                         }
368 #endif
369                 }
370
371                 public void MergeWith(FontInfo f) 
372                 {
373                         //Methods CopyFrom and MergeWith behave differently between 1.1 and 2.0
374 #if NET_2_0
375                         if (!_owner.CheckBit ((int) Style.Styles.FontBold) && f._owner.CheckBit ((int) Style.Styles.FontBold)) {
376                                 this.Bold = f.Bold;
377                         }
378
379                         if (!_owner.CheckBit ((int) Style.Styles.FontItalic) && f._owner.CheckBit ((int) Style.Styles.FontItalic)) {
380                                 this.Italic = f.Italic;
381                         }
382
383                         if (!_owner.CheckBit ((int) Style.Styles.FontNames) && f._owner.CheckBit ((int) Style.Styles.FontNames)) {
384                                 this.Names = f.Names;
385                         }
386
387                         if (!_owner.CheckBit ((int) Style.Styles.FontOverline) && f._owner.CheckBit ((int) Style.Styles.FontOverline)) {
388                                 this.Overline = f.Overline;
389                         }
390
391                         if (!_owner.CheckBit ((int) Style.Styles.FontSize) && f._owner.CheckBit ((int) Style.Styles.FontSize)) {
392                                 this.Size = f.Size;
393                         }
394
395                         if (!_owner.CheckBit ((int) Style.Styles.FontStrikeout) && f._owner.CheckBit ((int) Style.Styles.FontStrikeout)) {
396                                 this.Strikeout = f.Strikeout;
397                         }
398
399                         if (!_owner.CheckBit ((int) Style.Styles.FontUnderline) && f._owner.CheckBit ((int) Style.Styles.FontUnderline)) {
400                                 this.Underline = f.Underline;
401                         }
402 #else
403                         if (!_owner.CheckBit ((int) Style.Styles.FontBold) && f._owner.CheckBit ((int) Style.Styles.FontBold) && f.Bold) 
404                         {
405                                 this.Bold = true;
406                         }
407
408                         if (!_owner.CheckBit ((int) Style.Styles.FontItalic) && f._owner.CheckBit ((int) Style.Styles.FontItalic) && f.Italic) 
409                         {
410                                 this.Italic = true;
411                         }
412
413                         if (!_owner.CheckBit ((int) Style.Styles.FontNames) && f._owner.CheckBit ((int) Style.Styles.FontNames)) 
414                         {
415                                 this.Names = f.Names;
416                         }
417
418                         if (!_owner.CheckBit ((int) Style.Styles.FontOverline) && f._owner.CheckBit ((int) Style.Styles.FontOverline) && f.Overline) 
419                         {
420                                 this.Overline = true;
421                         }
422
423                         if (!_owner.CheckBit ((int) Style.Styles.FontSize) && f._owner.CheckBit ((int) Style.Styles.FontSize)) 
424                         {
425                                 this.Size = f.Size;
426                         }
427
428                         if (!_owner.CheckBit ((int) Style.Styles.FontStrikeout) && f._owner.CheckBit ((int) Style.Styles.FontStrikeout)) 
429                         {
430                                 this.Strikeout = true;
431                         }
432
433                         if (!_owner.CheckBit ((int) Style.Styles.FontUnderline) && f._owner.CheckBit ((int) Style.Styles.FontUnderline) && f.Underline) 
434                         {
435                                 this.Underline = true;
436                         }
437 #endif
438                 }
439
440                 public bool ShouldSerializeNames() 
441                 {
442                         return (Names.Length != 0);
443                 }
444
445                 public override string ToString() 
446                 {
447                         if (this.Names.Length == 0) 
448                         {
449                                 return this.Size.ToString();
450                         }
451
452                         return this.Name + ", " + this.Size.ToString();
453                 }
454 #if NET_2_0
455
456                 public void ClearDefaults () {
457                         Reset ();
458                 }
459
460 #endif
461                 #endregion      // Public Instance Methods
462
463                 #region Private Methods
464                 internal void Reset() 
465                 {
466                         bag.Remove("Font_Bold");
467                         bag.Remove("Font_Italic");
468                         bag.Remove("Font_Names");
469                         bag.Remove("Font_Overline");
470                         bag.Remove("Font_Size");
471                         bag.Remove("Font_Strikeout");
472                         bag.Remove("Font_Underline");
473                         _owner.RemoveBit ((int) Style.Styles.FontAll);
474                 }
475
476 #if NET_2_0
477                 internal void FillStyleAttributes (CssStyleCollection attributes, bool alwaysRenderTextDecoration) {
478                         if (IsEmpty) {
479                                 if(alwaysRenderTextDecoration)
480                                         attributes.Add (HtmlTextWriterStyle.TextDecoration, "none");
481                                 return;
482                         }
483
484                         string s;
485                         // Fonts are a bit weird
486                         s = String.Join (",", Names);
487                         if (s.Length > 0) {
488                                 attributes.Add (HtmlTextWriterStyle.FontFamily, s);
489                         }
490
491                         if (_owner.CheckBit ((int) Style.Styles.FontBold)) {
492                                 attributes.Add (HtmlTextWriterStyle.FontWeight, Bold ? "bold" : "normal");
493                         }
494
495                         if (_owner.CheckBit ((int) Style.Styles.FontItalic)) {
496                                 attributes.Add (HtmlTextWriterStyle.FontStyle, Italic ? "italic" : "normal");
497                         }
498
499                         if (!Size.IsEmpty) {
500                                 attributes.Add (HtmlTextWriterStyle.FontSize, Size.ToString ());
501                         }
502
503                         // These styles are munged into a attribute decoration
504                         s = string.Empty;
505                         bool hasTextDecoration = false;
506
507                         if (_owner.CheckBit ((int) Style.Styles.FontOverline)) {
508                                 if (Overline)
509                                         s += "overline ";
510                                 hasTextDecoration = true;
511                         }
512
513                         if (_owner.CheckBit ((int) Style.Styles.FontStrikeout)) {
514                                 if (Strikeout)
515                                         s += "line-through ";
516                                 hasTextDecoration = true;
517                         }
518
519                         if (_owner.CheckBit ((int) Style.Styles.FontUnderline)) {
520                                 if (Underline)
521                                         s += "underline ";
522                                 hasTextDecoration = true;
523                         }
524
525                         s = (s.Length > 0) ? s.Trim () : (alwaysRenderTextDecoration || hasTextDecoration) ? "none" : "";
526                         if (s.Length > 0)
527                                 attributes.Add (HtmlTextWriterStyle.TextDecoration, s);
528                 }
529 #endif
530                 #endregion      // Private Methods
531
532
533                 bool IsEmpty {
534                         get {
535                                 return !_owner.CheckBit ((int) Style.Styles.FontAll);
536                         }
537                 }
538         }
539 }