[MWF] Use full width for measuring text
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TextRenderer.cs
1 //
2 // TextRenderer.cs
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 //
23 // Copyright (c) 2006 Novell, Inc.
24 //
25 // Authors:
26 //      Jonathan Pobst (monkey@jpobst.com)
27 //
28
29 // This has become a monster class for all things text measuring and drawing.
30 //
31 // The public API is MeasureText/DrawText, which uses GDI on Win32, and
32 // GDI+ on other platforms.
33 //
34 // There is an internal API MeasureTextInternal/DrawTextInternal, which allows
35 // you to pass a flag of whether to use GDI or GDI+.  This is used mainly for
36 // controls that have the UseCompatibleTextRendering flag.
37 //
38 // There are also thread-safe versions of MeasureString/MeasureCharacterRanges
39 // for things that want to measure strings without having a Graphics object.
40
41 using System.Drawing;
42 using System.Runtime.InteropServices;
43 using System.Text;
44 using System.Drawing.Text;
45
46 namespace System.Windows.Forms
47 {
48         public sealed class TextRenderer
49         {
50                 private TextRenderer ()
51                 {
52                 }
53
54                 #region Public Methods
55                 public static void DrawText (IDeviceContext dc, string text, Font font, Point pt, Color foreColor)
56                 {
57                         DrawTextInternal (dc, text, font, pt, foreColor, Color.Transparent, TextFormatFlags.Default, false);
58                 }
59
60                 public static void DrawText (IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor)
61                 {
62                         DrawTextInternal (dc, text, font, bounds, foreColor, Color.Transparent, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter, false);
63                 }
64
65                 public static void DrawText (IDeviceContext dc, string text, Font font, Point pt, Color foreColor, Color backColor)
66                 {
67                         DrawTextInternal (dc, text, font, pt, foreColor, backColor, TextFormatFlags.Default, false);
68                 }
69
70                 public static void DrawText (IDeviceContext dc, string text, Font font, Point pt, Color foreColor, TextFormatFlags flags)
71                 {
72                         DrawTextInternal (dc, text, font, pt, foreColor, Color.Transparent, flags, false);
73                 }
74
75                 public static void DrawText (IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, Color backColor)
76                 {
77                         DrawTextInternal (dc, text, font, bounds, foreColor, backColor, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter, false);
78                 }
79
80                 public static void DrawText (IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, TextFormatFlags flags)
81                 {
82                         DrawTextInternal (dc, text, font, bounds, foreColor, Color.Transparent, flags, false);
83                 }
84
85                 public static void DrawText (IDeviceContext dc, string text, Font font, Point pt, Color foreColor, Color backColor, TextFormatFlags flags)
86                 {
87                         DrawTextInternal (dc, text, font, pt, foreColor, backColor, flags, false);
88                 }
89
90                 public static void DrawText (IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, Color backColor, TextFormatFlags flags)
91                 {
92                         DrawTextInternal (dc, text, font, bounds, foreColor, backColor, flags, false);
93                 }
94
95                 public static Size MeasureText (string text, Font font)
96                 {
97                         return MeasureTextInternal (Hwnd.GraphicsContext, text, font, Size.Empty, TextFormatFlags.Default, false);
98                 }
99
100                 public static Size MeasureText (IDeviceContext dc, string text, Font font)
101                 {
102                         return MeasureTextInternal (dc, text, font, Size.Empty, TextFormatFlags.Default, false);
103                 }
104
105                 public static Size MeasureText (string text, Font font, Size proposedSize)
106                 {
107                         return MeasureTextInternal (Hwnd.GraphicsContext, text, font, proposedSize, TextFormatFlags.Default, false);
108                 }
109
110                 public static Size MeasureText (IDeviceContext dc, string text, Font font, Size proposedSize)
111                 {
112                         return MeasureTextInternal (dc, text, font, proposedSize, TextFormatFlags.Default, false);
113                 }
114
115                 public static Size MeasureText (string text, Font font, Size proposedSize, TextFormatFlags flags)
116                 {
117                         return MeasureTextInternal (Hwnd.GraphicsContext, text, font, proposedSize, flags, false);
118                 }
119
120                 public static Size MeasureText (IDeviceContext dc, string text, Font font, Size proposedSize, TextFormatFlags flags)
121                 {
122                         return MeasureTextInternal (dc, text, font, proposedSize, flags, false);
123                 }
124                 #endregion
125
126                 #region Internal Methods That Do Stuff
127                 internal static void DrawTextInternal (IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, Color backColor, TextFormatFlags flags, bool useDrawString)
128                 {
129                         if (dc == null)
130                                 throw new ArgumentNullException ("dc");
131
132                         if (text == null || text.Length == 0)
133                                 return;
134
135                         // We use MS GDI API's unless told not to, or we aren't on Windows
136                         if (!useDrawString && !XplatUI.RunningOnUnix) {
137                                 if ((flags & TextFormatFlags.VerticalCenter) == TextFormatFlags.VerticalCenter || (flags & TextFormatFlags.Bottom) == TextFormatFlags.Bottom)
138                                         flags |= TextFormatFlags.SingleLine;
139
140                                 // Calculate the text bounds (there is often padding added)
141                                 Rectangle new_bounds = PadRectangle (bounds, flags);
142                                 new_bounds.Offset ((int)(dc as Graphics).Transform.OffsetX, (int)(dc as Graphics).Transform.OffsetY);
143
144                                 IntPtr hdc = IntPtr.Zero;
145                                 bool clear_clip_region = false;
146                                 
147                                 // If we need to use the graphics clipping region, add it to our hdc
148                                 if ((flags & TextFormatFlags.PreserveGraphicsClipping) == TextFormatFlags.PreserveGraphicsClipping) {
149                                         Graphics graphics = (Graphics)dc;
150                                         Region clip_region = graphics.Clip;
151                                         
152                                         if (!clip_region.IsInfinite (graphics)) {
153                                                 IntPtr hrgn = clip_region.GetHrgn (graphics);
154                                                 hdc = dc.GetHdc ();
155                                                 SelectClipRgn (hdc, hrgn);
156                                                 DeleteObject (hrgn);
157                                                 
158                                                 clear_clip_region = true;
159                                         }
160                                 }
161                                 
162                                 if (hdc == IntPtr.Zero)
163                                         hdc = dc.GetHdc ();
164                                         
165                                 // Set the fore color
166                                 if (foreColor != Color.Empty)
167                                         SetTextColor (hdc, ColorTranslator.ToWin32 (foreColor));
168
169                                 // Set the back color
170                                 if (backColor != Color.Transparent && backColor != Color.Empty) {
171                                         SetBkMode (hdc, 2);     //1-Transparent, 2-Opaque
172                                         SetBkColor (hdc, ColorTranslator.ToWin32 (backColor));
173                                 }
174                                 else {
175                                         SetBkMode (hdc, 1);     //1-Transparent, 2-Opaque
176                                 }
177
178                                 XplatUIWin32.RECT r = XplatUIWin32.RECT.FromRectangle (new_bounds);
179
180                                 IntPtr prevobj;
181
182                                 if (font != null) {
183                                         prevobj = SelectObject (hdc, font.ToHfont ());
184                                         Win32DrawText (hdc, text, text.Length, ref r, (int)flags);
185                                         prevobj = SelectObject (hdc, prevobj);
186                                         DeleteObject (prevobj);
187                                 }
188                                 else {
189                                         Win32DrawText (hdc, text, text.Length, ref r, (int)flags);
190                                 }
191
192                                 if (clear_clip_region)
193                                         SelectClipRgn (hdc, IntPtr.Zero);
194
195                                 dc.ReleaseHdc ();
196                         }
197                         // Use Graphics.DrawString as a fallback method
198                         else {
199                                 Graphics g;
200                                 IntPtr hdc = IntPtr.Zero;
201                                 
202                                 if (dc is Graphics)
203                                         g = (Graphics)dc;
204                                 else {
205                                         hdc = dc.GetHdc ();
206                                         g = Graphics.FromHdc (hdc);
207                                 }
208
209                                 StringFormat sf = FlagsToStringFormat (flags);
210
211                                 Rectangle new_bounds = PadDrawStringRectangle (bounds, flags);
212
213                                 g.DrawString (text, font, ThemeEngine.Current.ResPool.GetSolidBrush (foreColor), new_bounds, sf);
214
215                                 if (!(dc is Graphics)) {
216                                         g.Dispose ();
217                                         dc.ReleaseHdc ();
218                                 }
219                         }
220                 }
221
222                 internal static Size MeasureTextInternal (IDeviceContext dc, string text, Font font, Size proposedSize, TextFormatFlags flags, bool useMeasureString)
223                 {
224                         if (!useMeasureString && !XplatUI.RunningOnUnix) {
225                                 // Tell DrawText to calculate size instead of draw
226                                 flags |= (TextFormatFlags)1024;         // DT_CALCRECT
227
228                                 IntPtr hdc = dc.GetHdc ();
229
230                                 XplatUIWin32.RECT r = XplatUIWin32.RECT.FromRectangle (new Rectangle (Point.Empty, proposedSize));
231
232                                 IntPtr prevobj;
233
234                                 if (font != null) {
235                                         prevobj = SelectObject (hdc, font.ToHfont ());
236                                         Win32DrawText (hdc, text, text.Length, ref r, (int)flags);
237                                         prevobj = SelectObject (hdc, prevobj);
238                                         DeleteObject (prevobj);
239                                 }
240                                 else {
241                                         Win32DrawText (hdc, text, text.Length, ref r, (int)flags);
242                                 }
243
244                                 dc.ReleaseHdc ();
245
246                                 // Really, I am just making something up here, which as far as I can tell, MS
247                                 // just makes something up as well.  This will require lots of tweaking to match MS.  :(
248                                 Size retval = r.ToRectangle ().Size;
249
250                                 if (retval.Width > 0 && (flags & TextFormatFlags.NoPadding) == 0) {
251                                         retval.Width += 6;
252                                         retval.Width += (int)retval.Height / 8;
253                                 }
254
255                                 return retval;
256                         }
257                         else {
258                         StringFormat sf = FlagsToStringFormat (flags);
259
260                                 Size retval;
261
262                                 int proposedWidth;
263                                 if (proposedSize.Width == 0)
264                                         proposedWidth = Int32.MaxValue;
265                                 else {
266                                         proposedWidth = proposedSize.Width;
267                                         if ((flags & TextFormatFlags.NoPadding) == 0)
268                                                 proposedWidth -= 9;
269                                 }
270                                 if (dc is Graphics)
271                                         retval = (dc as Graphics).MeasureString (text, font, proposedWidth, sf).ToSize ();
272                                 else
273                                         retval = TextRenderer.MeasureString (text, font, proposedWidth, sf).ToSize ();
274
275                                 if (retval.Width > 0 && (flags & TextFormatFlags.NoPadding) == 0)
276                                         retval.Width += 9;
277
278                                 return retval;
279                         }
280                 }
281                 #endregion
282
283 #region Internal Methods That Are Just Overloads
284                 internal static void DrawTextInternal (IDeviceContext dc, string text, Font font, Point pt, Color foreColor, bool useDrawString)
285                 {
286                         DrawTextInternal (dc, text, font, pt, foreColor, Color.Transparent, TextFormatFlags.Default, useDrawString);
287                 }
288
289                 internal static void DrawTextInternal (IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, bool useDrawString)
290                 {
291                         DrawTextInternal (dc, text, font, bounds, foreColor, Color.Transparent, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter, useDrawString);
292                 }
293
294                 internal static void DrawTextInternal (IDeviceContext dc, string text, Font font, Point pt, Color foreColor, Color backColor, bool useDrawString)
295                 {
296                         DrawTextInternal (dc, text, font, pt, foreColor, backColor, TextFormatFlags.Default, useDrawString);
297                 }
298
299                 internal static void DrawTextInternal (IDeviceContext dc, string text, Font font, Point pt, Color foreColor, TextFormatFlags flags, bool useDrawString)
300                 {
301                         DrawTextInternal (dc, text, font, pt, foreColor, Color.Transparent, flags, useDrawString);
302                 }
303
304                 internal static void DrawTextInternal (IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, Color backColor, bool useDrawString)
305                 {
306                         DrawTextInternal (dc, text, font, bounds, foreColor, backColor, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter, useDrawString);
307                 }
308
309                 internal static void DrawTextInternal (IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, TextFormatFlags flags, bool useDrawString)
310                 {
311                         DrawTextInternal (dc, text, font, bounds, foreColor, Color.Transparent, flags, useDrawString);
312                 }
313
314                 internal static Size MeasureTextInternal (string text, Font font, bool useMeasureString)
315                 {
316                         return MeasureTextInternal (Hwnd.GraphicsContext, text, font, Size.Empty, TextFormatFlags.Default, useMeasureString);
317                 }
318
319                 internal static void DrawTextInternal (IDeviceContext dc, string text, Font font, Point pt, Color foreColor, Color backColor, TextFormatFlags flags, bool useDrawString)
320                 {
321                         Size sz = MeasureTextInternal (dc, text, font, useDrawString);
322                         DrawTextInternal (dc, text, font, new Rectangle (pt, sz), foreColor, backColor, flags, useDrawString);
323                 }
324
325                 internal static Size MeasureTextInternal (IDeviceContext dc, string text, Font font, bool useMeasureString)
326                 {
327                         return MeasureTextInternal (dc, text, font, Size.Empty, TextFormatFlags.Default, useMeasureString);
328                 }
329
330                 internal static Size MeasureTextInternal (string text, Font font, Size proposedSize, bool useMeasureString)
331                 {
332                         return MeasureTextInternal (Hwnd.GraphicsContext, text, font, proposedSize, TextFormatFlags.Default, useMeasureString);
333                 }
334
335                 internal static Size MeasureTextInternal (IDeviceContext dc, string text, Font font, Size proposedSize, bool useMeasureString)
336                 {
337                         return MeasureTextInternal (dc, text, font, proposedSize, TextFormatFlags.Default, useMeasureString);
338                 }
339
340                 internal static Size MeasureTextInternal (string text, Font font, Size proposedSize, TextFormatFlags flags, bool useMeasureString)
341                 {
342                         return MeasureTextInternal (Hwnd.GraphicsContext, text, font, proposedSize, flags, useMeasureString);
343                 }
344 #endregion
345
346                 #region Thread-Safe Static Graphics Methods
347                 internal static SizeF MeasureString (string text, Font font)
348                 {
349                         return Hwnd.GraphicsContext.MeasureString (text, font);
350                 }
351
352                 internal static SizeF MeasureString (string text, Font font, int width)
353                 {
354                         return Hwnd.GraphicsContext.MeasureString (text, font, width);
355                 }
356
357                 internal static SizeF MeasureString (string text, Font font, SizeF layoutArea)
358                 {
359                         return Hwnd.GraphicsContext.MeasureString (text, font, layoutArea);
360                 }
361
362                 internal static SizeF MeasureString (string text, Font font, int width, StringFormat format)
363                 {
364                         return Hwnd.GraphicsContext.MeasureString (text, font, width, format);
365                 }
366
367                 internal static SizeF MeasureString (string text, Font font, PointF origin, StringFormat stringFormat)
368                 {
369                         return Hwnd.GraphicsContext.MeasureString (text, font, origin, stringFormat);
370                 }
371
372                 internal static SizeF MeasureString (string text, Font font, SizeF layoutArea, StringFormat stringFormat)
373                 {
374                         return Hwnd.GraphicsContext.MeasureString (text, font, layoutArea, stringFormat);
375                 }
376
377                 internal static SizeF MeasureString (string text, Font font, SizeF layoutArea, StringFormat stringFormat, out int charactersFitted, out int linesFilled)
378                 {
379                         return Hwnd.GraphicsContext.MeasureString (text, font, layoutArea, stringFormat, out charactersFitted, out linesFilled);
380                 }
381
382                 internal static Region[] MeasureCharacterRanges (string text, Font font, RectangleF layoutRect, StringFormat stringFormat)
383                 {
384                         return Hwnd.GraphicsContext.MeasureCharacterRanges (text, font, layoutRect, stringFormat);
385                 }
386                 
387                 internal static SizeF GetDpi ()
388                 {
389                         return new SizeF (Hwnd.GraphicsContext.DpiX, Hwnd.GraphicsContext.DpiY);
390                 }
391                 #endregion
392                 
393 #region Private Methods
394                 private static StringFormat FlagsToStringFormat (TextFormatFlags flags)
395                 {
396                         StringFormat sf = new StringFormat ();
397
398                         // Translation table: http://msdn.microsoft.com/msdnmag/issues/06/03/TextRendering/default.aspx?fig=true#fig4
399
400                         // Horizontal Alignment
401                         if ((flags & TextFormatFlags.HorizontalCenter) == TextFormatFlags.HorizontalCenter)
402                                 sf.Alignment = StringAlignment.Center;
403                         else if ((flags & TextFormatFlags.Right) == TextFormatFlags.Right)
404                                 sf.Alignment = StringAlignment.Far;
405                         else
406                                 sf.Alignment = StringAlignment.Near;
407
408                         // Vertical Alignment
409                         if ((flags & TextFormatFlags.Bottom) == TextFormatFlags.Bottom)
410                                 sf.LineAlignment = StringAlignment.Far;
411                         else if ((flags & TextFormatFlags.VerticalCenter) == TextFormatFlags.VerticalCenter)
412                                 sf.LineAlignment = StringAlignment.Center;
413                         else
414                                 sf.LineAlignment = StringAlignment.Near;
415
416                         // Ellipsis
417                         if ((flags & TextFormatFlags.EndEllipsis) == TextFormatFlags.EndEllipsis)
418                                 sf.Trimming = StringTrimming.EllipsisCharacter;
419                         else if ((flags & TextFormatFlags.PathEllipsis) == TextFormatFlags.PathEllipsis)
420                                 sf.Trimming = StringTrimming.EllipsisPath;
421                         else if ((flags & TextFormatFlags.WordEllipsis) == TextFormatFlags.WordEllipsis)
422                                 sf.Trimming = StringTrimming.EllipsisWord;
423                         else
424                                 sf.Trimming = StringTrimming.Character;
425
426                         // Hotkey Prefix
427                         if ((flags & TextFormatFlags.NoPrefix) == TextFormatFlags.NoPrefix)
428                                 sf.HotkeyPrefix = HotkeyPrefix.None;
429                         else if ((flags & TextFormatFlags.HidePrefix) == TextFormatFlags.HidePrefix)
430                                 sf.HotkeyPrefix = HotkeyPrefix.Hide;
431                         else
432                                 sf.HotkeyPrefix = HotkeyPrefix.Show;
433
434                         // Text Padding
435                         if ((flags & TextFormatFlags.NoPadding) == TextFormatFlags.NoPadding)
436                                 sf.FormatFlags |= StringFormatFlags.FitBlackBox;
437
438                         // Text Wrapping
439                         if ((flags & TextFormatFlags.SingleLine) == TextFormatFlags.SingleLine)
440                                 sf.FormatFlags |= StringFormatFlags.NoWrap;
441                         else if ((flags & TextFormatFlags.TextBoxControl) == TextFormatFlags.TextBoxControl)
442                                 sf.FormatFlags |= StringFormatFlags.LineLimit;
443
444                         // Other Flags
445                         //if ((flags & TextFormatFlags.RightToLeft) == TextFormatFlags.RightToLeft)
446                         //        sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
447                         if ((flags & TextFormatFlags.NoClipping) == TextFormatFlags.NoClipping)
448                                 sf.FormatFlags |= StringFormatFlags.NoClip;
449
450                         return sf;
451                 }
452
453                 private static Rectangle PadRectangle (Rectangle r, TextFormatFlags flags)
454                 {
455                         if ((flags & TextFormatFlags.NoPadding) == 0 && (flags & TextFormatFlags.Right) == 0 && (flags & TextFormatFlags.HorizontalCenter) == 0) {
456                                 r.X += 3;
457                                 r.Width -= 3;
458                         }
459                         if ((flags & TextFormatFlags.NoPadding) == 0 && (flags & TextFormatFlags.Right) == TextFormatFlags.Right) {
460                                 r.Width -= 4;
461                         }
462                         if ((flags & TextFormatFlags.LeftAndRightPadding) == TextFormatFlags.LeftAndRightPadding) {
463                                 r.X += 2;
464                                 r.Width -= 2;
465                         }
466                         if ((flags & TextFormatFlags.WordEllipsis) == TextFormatFlags.WordEllipsis || (flags & TextFormatFlags.EndEllipsis) == TextFormatFlags.EndEllipsis || (flags & TextFormatFlags.WordBreak) == TextFormatFlags.WordBreak) {
467                                 r.Width -= 4;
468                         }
469                         if ((flags & TextFormatFlags.VerticalCenter) == TextFormatFlags.VerticalCenter) {
470                                 r.Y += 1;
471                         }
472
473                         return r;
474                 }
475
476                 private static Rectangle PadDrawStringRectangle (Rectangle r, TextFormatFlags flags)
477                 {
478                         if ((flags & TextFormatFlags.NoPadding) == 0 && (flags & TextFormatFlags.Right) == 0 && (flags & TextFormatFlags.HorizontalCenter) == 0) {
479                                 r.X += 1;
480                                 r.Width -= 1;
481                         }
482                         if ((flags & TextFormatFlags.NoPadding) == 0 && (flags & TextFormatFlags.Right) == TextFormatFlags.Right) {
483                                 r.Width -= 4;
484                         }
485                         if ((flags & TextFormatFlags.NoPadding) == TextFormatFlags.NoPadding) {
486                                 r.X -= 2;
487                         }
488                         if ((flags & TextFormatFlags.NoPadding) == 0 && (flags & TextFormatFlags.Bottom) == TextFormatFlags.Bottom) {
489                                 r.Y += 1;
490                         }
491                         if ((flags & TextFormatFlags.LeftAndRightPadding) == TextFormatFlags.LeftAndRightPadding) {
492                                 r.X += 2;
493                                 r.Width -= 2;
494                         }
495                         if ((flags & TextFormatFlags.WordEllipsis) == TextFormatFlags.WordEllipsis || (flags & TextFormatFlags.EndEllipsis) == TextFormatFlags.EndEllipsis || (flags & TextFormatFlags.WordBreak) == TextFormatFlags.WordBreak) {
496                                 r.Width -= 4;
497                         }
498                         if ((flags & TextFormatFlags.VerticalCenter) == TextFormatFlags.VerticalCenter && XplatUI.RunningOnUnix) {
499                                 r.Y -= 1;
500                         }
501
502                         return r;
503                 }
504 #endregion
505
506 #region DllImports (Windows)
507                 [DllImport ("user32", CharSet = CharSet.Unicode, EntryPoint = "DrawText")]
508                 static extern int Win32DrawText (IntPtr hdc, string lpStr, int nCount, ref XplatUIWin32.RECT lpRect, int wFormat);
509
510                 [DllImport ("gdi32")]
511                 static extern int SetTextColor (IntPtr hdc, int crColor);
512
513                 [DllImport ("gdi32")]
514                 static extern IntPtr SelectObject (IntPtr hDC, IntPtr hObject);
515
516                 [DllImport ("gdi32")]
517                 static extern int SetBkColor (IntPtr hdc, int crColor);
518
519                 [DllImport ("gdi32")]
520                 static extern int SetBkMode (IntPtr hdc, int iBkMode);
521
522                 [DllImport ("gdi32")]
523                 static extern bool DeleteObject (IntPtr objectHandle);
524
525                 [DllImport("gdi32")]
526                 static extern bool SelectClipRgn(IntPtr hdc, IntPtr hrgn);
527 #endregion
528         }
529 }