4 // Permission is hereby granted, free of charge, to any person obtaining
\r
5 // a copy of this software and associated documentation files (the
\r
6 // "Software"), to deal in the Software without restriction, including
\r
7 // without limitation the rights to use, copy, modify, merge, publish,
\r
8 // distribute, sublicense, and/or sell copies of the Software, and to
\r
9 // permit persons to whom the Software is furnished to do so, subject to
\r
10 // the following conditions:
\r
12 // The above copyright notice and this permission notice shall be
\r
13 // included in all copies or substantial portions of the Software.
\r
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
23 // Copyright (c) 2006 Novell, Inc.
\r
26 // Jonathan Pobst (monkey@jpobst.com)
\r
30 using System.Drawing;
\r
31 using System.Runtime.InteropServices;
\r
33 using System.Drawing.Text;
\r
35 namespace System.Windows.Forms
\r
37 public sealed class TextRenderer
\r
39 #region Public Methods
\r
40 [MonoTODO("This should be correct for Windows, other platforms need a more accurate fallback method than the one provided")]
\r
41 public static void DrawText (IDeviceContext dc, string text, Font font, Rectangle bounds, Color foreColor, TextFormatFlags flags)
\r
43 if (Environment.OSVersion.Platform == PlatformID.Win32NT || Environment.OSVersion.Platform == PlatformID.Win32Windows) {
\r
44 IntPtr hdc = dc.GetHdc ();
\r
46 SetTextColor (hdc, ColorTranslator.ToWin32 (foreColor));
\r
47 SetBkMode (hdc, 1); //1-Transparent, 2-Opaque
\r
49 VisualStyles.UXTheme.RECT r = VisualStyles.UXTheme.RECT.FromRectangle (bounds);
\r
52 SelectObject (hdc, font.ToHfont ());
\r
54 DrawText (hdc, text, text.Length, ref r, (int)flags);
\r
63 g = Graphics.FromHdc (dc.GetHdc ());
\r
65 StringFormat sf = FlagsToStringFormat (flags);
\r
67 using (Brush b = new SolidBrush (foreColor))
\r
68 g.DrawString (text, font, b, bounds, sf);
\r
70 if (!(dc is Graphics)) {
\r
77 [MonoTODO ("This should be correct for Windows, other platforms need a more accurate fallback method than the one provided")]
\r
78 public static void DrawText (IDeviceContext dc, string text, Font font, Point pt, Color foreColor, TextFormatFlags flags)
\r
80 if (Environment.OSVersion.Platform == PlatformID.Win32NT || Environment.OSVersion.Platform == PlatformID.Win32Windows) {
\r
81 IntPtr hdc = dc.GetHdc ();
\r
83 SetTextColor (hdc, ColorTranslator.ToWin32 (foreColor));
\r
84 SetBkMode (hdc, 1); //1-Transparent, 2-Opaque
\r
86 Size sz = MeasureText(text, font);
\r
88 VisualStyles.UXTheme.RECT r = new System.Windows.Forms.VisualStyles.UXTheme.RECT(pt.X, pt.Y, pt.X + sz.Width, pt.Y + sz.Height);
\r
91 SelectObject (hdc, font.ToHfont ());
\r
93 DrawText (hdc, text, text.Length, ref r, (int)flags);
\r
102 g = Graphics.FromHdc (dc.GetHdc ());
\r
104 StringFormat sf = FlagsToStringFormat (flags);
\r
106 using (Brush b = new SolidBrush (foreColor))
\r
107 g.DrawString (text, font, b, pt, sf);
\r
109 if (!(dc is Graphics)) {
\r
116 [MonoTODO ("This should be correct for Windows, other platforms need a more accurate fallback method than the one provided")]
\r
117 public static Size MeasureText (string text, Font font)
\r
119 if (Environment.OSVersion.Platform == PlatformID.Win32NT || Environment.OSVersion.Platform == PlatformID.Win32Windows) {
\r
120 Bitmap b = new Bitmap (5, 5);
\r
121 Graphics g = Graphics.FromImage (b);
\r
123 IntPtr hdc = g.GetHdc ();
\r
126 SelectObject (hdc, font.ToHfont ());
\r
128 VisualStyles.UXTheme.SIZE text_size = new System.Windows.Forms.VisualStyles.UXTheme.SIZE();
\r
130 GetTextExtentPoint32 (hdc, text, text.Length, out text_size);
\r
134 return text_size.ToSize();
\r
137 Bitmap b = new Bitmap (5, 5);
\r
138 Graphics g = Graphics.FromImage (b);
\r
140 return g.MeasureString(text,font).ToSize();
\r
145 #region Private Methods
\r
146 private static StringFormat FlagsToStringFormat (TextFormatFlags flags)
\r
148 StringFormat sf = new StringFormat ();
\r
150 // Translation table: http://msdn.microsoft.com/msdnmag/issues/06/03/TextRendering/default.aspx?fig=true#fig4
\r
152 // Horizontal Alignment
\r
153 if ((flags & TextFormatFlags.HorizontalCenter) == TextFormatFlags.HorizontalCenter)
\r
154 sf.Alignment = StringAlignment.Center;
\r
155 else if ((flags & TextFormatFlags.Right) == TextFormatFlags.Right)
\r
156 sf.Alignment = StringAlignment.Far;
\r
158 sf.Alignment = StringAlignment.Near;
\r
160 // Vertical Alignment
\r
161 if ((flags & TextFormatFlags.Bottom) == TextFormatFlags.Bottom)
\r
162 sf.LineAlignment = StringAlignment.Far;
\r
163 else if ((flags & TextFormatFlags.VerticalCenter) == TextFormatFlags.VerticalCenter)
\r
164 sf.LineAlignment = StringAlignment.Center;
\r
166 sf.LineAlignment = StringAlignment.Near;
\r
169 if ((flags & TextFormatFlags.EndEllipsis) == TextFormatFlags.EndEllipsis)
\r
170 sf.Trimming = StringTrimming.EllipsisCharacter;
\r
171 else if ((flags & TextFormatFlags.PathEllipsis) == TextFormatFlags.PathEllipsis)
\r
172 sf.Trimming = StringTrimming.EllipsisPath;
\r
173 else if ((flags & TextFormatFlags.WordEllipsis) == TextFormatFlags.WordEllipsis)
\r
174 sf.Trimming = StringTrimming.EllipsisWord;
\r
176 sf.Trimming = StringTrimming.Character;
\r
179 if ((flags & TextFormatFlags.NoPrefix) == TextFormatFlags.NoPrefix)
\r
180 sf.HotkeyPrefix = HotkeyPrefix.None;
\r
181 else if ((flags & TextFormatFlags.HidePrefix) == TextFormatFlags.HidePrefix)
\r
182 sf.HotkeyPrefix = HotkeyPrefix.Hide;
\r
184 sf.HotkeyPrefix = HotkeyPrefix.Show;
\r
187 if ((flags & TextFormatFlags.NoPadding) == TextFormatFlags.NoPadding)
\r
188 sf.FormatFlags |= StringFormatFlags.FitBlackBox;
\r
191 if ((flags & TextFormatFlags.SingleLine) == TextFormatFlags.SingleLine)
\r
192 sf.FormatFlags |= StringFormatFlags.NoWrap;
\r
193 else if ((flags & TextFormatFlags.TextBoxControl) == TextFormatFlags.TextBoxControl)
\r
194 sf.FormatFlags |= StringFormatFlags.LineLimit;
\r
197 if ((flags & TextFormatFlags.RightToLeft) == TextFormatFlags.RightToLeft)
\r
198 sf.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
\r
199 if ((flags & TextFormatFlags.NoClipping) == TextFormatFlags.NoClipping)
\r
200 sf.FormatFlags |= StringFormatFlags.NoClip;
\r
201 sf.FormatFlags |= StringFormatFlags.NoClip;
\r
207 #region DllImports (Windows)
\r
208 [DllImport ("user32", CharSet = CharSet.Unicode)]
\r
209 static extern int DrawText (IntPtr hdc, string lpStr, int nCount, ref VisualStyles.UXTheme.RECT lpRect, int wFormat);
\r
211 [DllImport ("gdi32")]
\r
212 static extern int SetTextColor (IntPtr hdc, int crColor);
\r
214 [DllImport ("gdi32")]
\r
215 private extern static IntPtr SelectObject (IntPtr hDC, IntPtr hObject);
\r
217 [DllImport ("gdi32")]
\r
218 static extern int SetBkColor (IntPtr hdc, int crColor);
\r
220 [DllImport ("gdi32")]
\r
221 static extern int SetBkMode (IntPtr hdc, int iBkMode);
\r
223 [DllImport ("gdi32")]
\r
224 static extern bool GetTextExtentExPoint (IntPtr hdc, string lpszStr, int cchString, int nMaxExtent, IntPtr lpnFit, IntPtr alpDx, out VisualStyles.UXTheme.SIZE lpSize);
\r
226 [DllImport ("gdi32")]
\r
227 static extern bool GetTextExtentPoint32 (IntPtr hdc, string lpString, int cbString, out VisualStyles.UXTheme.SIZE lpSize);
\r