2014-08-05 00:18:55 +00:00
using System ;
2014-10-22 07:59:06 +00:00
using System.Text ;
2014-08-05 00:18:55 +00:00
using System.Collections.Generic ;
using System.Drawing ;
using System.Runtime.InteropServices ;
namespace BizHawk.Client.EmuHawk.CustomControls
{
2014-08-10 22:23:14 +00:00
/// <summary>
/// Wrapper for GDI rendering functions
/// This class is not thread-safe as GDI functions should be called from the UI thread
/// </summary>
2014-08-07 18:32:09 +00:00
public sealed class GDIRenderer : IDisposable
2014-08-05 00:18:55 +00:00
{
2014-08-10 22:23:14 +00:00
/// <summary>
/// used for <see cref="MeasureString(string, System.Drawing.Font, float, out int, out int)"/> calculation.
/// </summary>
private static readonly int [ ] CharFit = new int [ 1 ] ;
2014-08-05 00:18:55 +00:00
2014-08-10 22:23:14 +00:00
/// <summary>
/// used for <see cref="MeasureString(string, System.Drawing.Font,float, out int, out int)"/> calculation
/// </summary>
private static readonly int [ ] CharFitWidth = new int [ 1000 ] ;
2014-08-05 00:18:55 +00:00
2014-08-10 22:23:14 +00:00
/// <summary>
2014-10-22 07:59:06 +00:00
/// Cache of all the HFONTs used, rather than create them again and again
2014-08-10 22:23:14 +00:00
/// </summary>
2015-07-07 19:05:05 +00:00
private readonly Dictionary < Font , FontCacheEntry > FontsCache = new Dictionary < Font , FontCacheEntry > ( ) ;
2014-10-22 07:59:06 +00:00
class FontCacheEntry
{
public IntPtr HFont ;
}
2014-08-05 00:18:55 +00:00
2014-08-10 22:23:14 +00:00
/// <summary>
/// Cache of all the brushes used, rather than create them again and again
/// </summary>
private readonly Dictionary < Color , IntPtr > BrushCache = new Dictionary < Color , IntPtr > ( ) ;
2014-08-05 00:18:55 +00:00
2014-08-10 18:49:17 +00:00
private Graphics _g ;
2014-08-05 00:18:55 +00:00
private IntPtr _hdc ;
2014-08-10 22:23:14 +00:00
private IntPtr _currentBrush = IntPtr . Zero ;
2014-08-05 00:18:55 +00:00
2014-08-10 22:23:14 +00:00
#region Construct and Destroy
2014-08-05 00:18:55 +00:00
2014-08-10 22:23:14 +00:00
public GDIRenderer ( )
2014-08-05 01:03:16 +00:00
{
2014-08-18 06:50:12 +00:00
SetBkMode ( _hdc , BkModes . OPAQUE ) ;
2014-08-10 22:23:14 +00:00
}
2014-08-10 18:49:17 +00:00
2014-08-10 22:23:14 +00:00
public void Dispose ( )
{
foreach ( var brush in BrushCache )
2014-08-10 18:49:17 +00:00
{
2014-08-10 22:23:14 +00:00
if ( brush . Value ! = IntPtr . Zero )
{
DeleteObject ( brush . Value ) ;
}
2014-08-10 18:49:17 +00:00
}
2014-10-22 07:59:06 +00:00
foreach ( var fc in FontsCache )
DeleteObject ( fc . Value . HFont ) ;
2014-08-18 00:23:09 +00:00
EndOffScreenBitmap ( ) ;
2014-08-10 22:23:14 +00:00
System . Diagnostics . Debug . Assert ( _hdc = = IntPtr . Zero , "Disposed a GDIRenderer while it held an HDC" ) ;
System . Diagnostics . Debug . Assert ( _g = = null , "Disposed a GDIRenderer while it held a Graphics" ) ;
2014-08-05 01:03:16 +00:00
}
2014-08-10 22:23:14 +00:00
#endregion
#region Api
2014-09-03 02:24:13 +00:00
/// <summary>
/// Draw a bitmap object at the given position
/// </summary>
2014-09-18 00:31:32 +00:00
public void DrawBitmap ( Bitmap bitmap , Point point , bool blend = false )
2014-09-03 02:24:13 +00:00
{
2014-09-03 02:52:46 +00:00
IntPtr hbmp = bitmap . GetHbitmap ( ) ;
2014-09-03 02:24:13 +00:00
var bitHDC = CreateCompatibleDC ( CurrentHDC ) ;
2014-10-22 07:59:06 +00:00
IntPtr old = SelectObject ( bitHDC , hbmp ) ;
2014-09-18 00:31:32 +00:00
if ( blend )
{
AlphaBlend ( CurrentHDC , point . X , point . Y , bitmap . Width , bitmap . Height , bitHDC , 0 , 0 , bitmap . Width , bitmap . Height , new BLENDFUNCTION ( AC_SRC_OVER , 0 , 0xff , AC_SRC_ALPHA ) ) ;
}
else
{
BitBlt ( CurrentHDC , point . X , point . Y , bitmap . Width , bitmap . Height , bitHDC , 0 , 0 , 0xCC0020 ) ;
}
2014-09-03 02:52:46 +00:00
SelectObject ( bitHDC , old ) ;
DeleteDC ( bitHDC ) ;
2014-10-11 18:56:54 +00:00
DeleteObject ( hbmp ) ;
2014-09-03 02:24:13 +00:00
}
2014-08-10 22:23:14 +00:00
/// <summary>
/// Required to use before calling drawing methods
/// </summary>
2014-08-10 18:49:17 +00:00
public GdiGraphicsLock LockGraphics ( Graphics g )
2014-08-09 16:50:38 +00:00
{
2014-08-10 18:49:17 +00:00
_g = g ;
_hdc = g . GetHdc ( ) ;
2014-08-18 06:50:12 +00:00
SetBkMode ( _hdc , BkModes . TRANSPARENT ) ;
2014-08-10 18:49:17 +00:00
return new GdiGraphicsLock ( this ) ;
2014-08-09 16:50:38 +00:00
}
2014-08-07 23:10:41 +00:00
/// <summary>
2014-08-10 22:23:14 +00:00
/// Measure the width and height of string <paramref name="str"/> when drawn on device context HDC
/// using the given font <paramref name="font"/>
2014-08-07 23:10:41 +00:00
/// </summary>
2014-08-05 00:18:55 +00:00
public Size MeasureString ( string str , Font font )
{
SetFont ( font ) ;
var size = new Size ( ) ;
2014-08-18 00:23:09 +00:00
GetTextExtentPoint32 ( CurrentHDC , str , str . Length , ref size ) ;
2014-08-05 00:18:55 +00:00
return size ;
}
/// <summary>
2014-08-10 22:23:14 +00:00
/// Measure the width and height of string <paramref name="str"/> when drawn on device context HDC
/// using the given font <paramref name="font"/>
/// Restrict the width of the string and get the number of characters able to fit in the restriction and
/// the width those characters take
/// </summary>
/// <param name="maxWidth">the max width to render the string in</param>
/// <param name="charFit">the number of characters that will fit under <see cref="maxWidth"/> restriction</param>
/// <param name="charFitWidth"></param>
2014-08-05 00:18:55 +00:00
public Size MeasureString ( string str , Font font , float maxWidth , out int charFit , out int charFitWidth )
{
SetFont ( font ) ;
var size = new Size ( ) ;
2014-08-18 00:23:09 +00:00
GetTextExtentExPoint ( CurrentHDC , str , str . Length , ( int ) Math . Round ( maxWidth ) , CharFit , CharFitWidth , ref size ) ;
2014-08-10 22:23:14 +00:00
charFit = CharFit [ 0 ] ;
charFitWidth = charFit > 0 ? CharFitWidth [ charFit - 1 ] : 0 ;
2014-08-05 00:18:55 +00:00
return size ;
}
2014-08-10 22:23:14 +00:00
public void DrawString ( string str , Point point )
2014-08-05 01:03:16 +00:00
{
2014-08-18 00:23:09 +00:00
TextOut ( CurrentHDC , point . X , point . Y , str , str . Length ) ;
2014-08-05 01:03:16 +00:00
}
2014-10-22 07:59:06 +00:00
//this returns an IntPtr HFONT because .net's Font class will erase the relevant properties when using its Font.FromLogFont()
//note that whether this is rotated clockwise or CCW might affect how you have to position the text (right-aligned sometimes?, up or down by the height of the font?)
public static IntPtr CreateRotatedHFont ( Font font , bool CW )
{
LOGFONT logf = new LOGFONT ( ) ;
//font.ToLogFont(logf);
//logf.lfEscapement = CW ? 2700 : 900;
logf . lfFaceName = "System" ;
logf . lfEscapement = 3600 - 450 ;
logf . lfOrientation = logf . lfEscapement ;
logf . lfOutPrecision = ( byte ) FontPrecision . OUT_TT_ONLY_PRECIS ;
//this doesnt work! .net erases the relevant propreties.. it seems?
//return Font.FromLogFont(logf);
var ret = CreateFontIndirect ( ref logf ) ;
return ret ;
}
public static void DestroyHFont ( IntPtr hfont )
{
DeleteObject ( hfont ) ;
}
public void PrepDrawString ( IntPtr hfont , Color color )
{
SetGraphicsMode ( CurrentHDC , 2 ) ; //shouldnt be necessary.. cant hurt
SelectObject ( _hdc , hfont ) ;
SetTextColor ( color ) ;
}
2014-08-10 21:35:17 +00:00
public void PrepDrawString ( Font font , Color color )
2014-08-05 00:18:55 +00:00
{
SetFont ( font ) ;
SetTextColor ( color ) ;
}
2014-10-22 07:59:06 +00:00
2014-08-10 22:23:14 +00:00
/// <summary>
/// Draw the given string using the given font and foreground color at given location
/// See [http://msdn.microsoft.com/en-us/library/windows/desktop/dd162498(v=vs.85).aspx][15]
/// </summary>
public void DrawString ( string str , Font font , Color color , Rectangle rect , TextFormatFlags flags )
2014-08-05 00:18:55 +00:00
{
SetFont ( font ) ;
SetTextColor ( color ) ;
var rect2 = new Rect ( rect ) ;
2014-08-18 00:23:09 +00:00
DrawText ( CurrentHDC , str , str . Length , ref rect2 , ( uint ) flags ) ;
2014-08-05 00:18:55 +00:00
}
2014-10-22 07:59:06 +00:00
2014-08-10 22:23:14 +00:00
/// <summary>
/// Set the text color of the device context
/// </summary>
2014-08-07 23:10:41 +00:00
public void SetTextColor ( Color color )
2014-08-05 00:18:55 +00:00
{
int rgb = ( color . B & 0xFF ) < < 16 | ( color . G & 0xFF ) < < 8 | color . R ;
2014-08-18 00:23:09 +00:00
SetTextColor ( CurrentHDC , rgb ) ;
2014-08-05 00:18:55 +00:00
}
2014-08-07 23:10:41 +00:00
public void SetBackgroundColor ( Color color )
{
int rgb = ( color . B & 0xFF ) < < 16 | ( color . G & 0xFF ) < < 8 | color . R ;
2014-08-18 00:23:09 +00:00
SetBkColor ( CurrentHDC , rgb ) ;
2014-08-07 23:10:41 +00:00
}
2014-08-07 23:52:19 +00:00
public void DrawRectangle ( int nLeftRect , int nTopRect , int nRightRect , int nBottomRect )
2014-08-05 01:03:16 +00:00
{
2014-08-18 00:23:09 +00:00
Rectangle ( CurrentHDC , nLeftRect , nTopRect , nRightRect , nBottomRect ) ;
2014-08-05 01:03:16 +00:00
}
2014-08-07 23:10:41 +00:00
public void SetBrush ( Color color )
{
2014-08-09 22:01:00 +00:00
if ( BrushCache . ContainsKey ( color ) )
{
_currentBrush = BrushCache [ color ] ;
}
else
{
int rgb = ( color . B & 0xFF ) < < 16 | ( color . G & 0xFF ) < < 8 | color . R ;
var newBrush = CreateSolidBrush ( rgb ) ;
BrushCache . Add ( color , newBrush ) ;
_currentBrush = newBrush ;
}
2014-08-07 23:10:41 +00:00
}
2014-08-10 22:23:14 +00:00
public void FillRectangle ( int x , int y , int w , int h )
2014-08-07 23:10:41 +00:00
{
2014-08-11 00:08:16 +00:00
var r = new GDIRect ( new Rectangle ( x , y , w , h ) ) ;
2014-08-18 00:23:09 +00:00
FillRect ( CurrentHDC , ref r , _currentBrush ) ;
2014-08-07 23:10:41 +00:00
}
2014-08-08 02:09:59 +00:00
public void SetPenPosition ( int x , int y )
{
2014-08-18 00:23:09 +00:00
MoveToEx ( CurrentHDC , x , y , IntPtr . Zero ) ;
2014-08-08 02:09:59 +00:00
}
2014-08-09 16:11:25 +00:00
public void SetSolidPen ( Color color )
{
int rgb = ( color . B & 0xFF ) < < 16 | ( color . G & 0xFF ) < < 8 | color . R ;
2014-08-18 00:23:09 +00:00
SelectObject ( CurrentHDC , GetStockObject ( ( int ) PaintObjects . DC_PEN ) ) ;
SetDCPenColor ( CurrentHDC , rgb ) ;
2014-08-09 16:11:25 +00:00
}
2014-08-08 02:09:59 +00:00
public void Line ( int x1 , int y1 , int x2 , int y2 )
{
2014-08-18 00:23:09 +00:00
MoveToEx ( CurrentHDC , x1 , y1 , IntPtr . Zero ) ;
LineTo ( CurrentHDC , x2 , y2 ) ;
}
private IntPtr CurrentHDC
{
get { return _bitHDC ! = IntPtr . Zero ? _bitHDC : _hdc ; }
}
2014-08-31 18:19:26 +00:00
private IntPtr _bitMap = IntPtr . Zero ;
private IntPtr _bitHDC = IntPtr . Zero ;
2014-08-18 00:23:09 +00:00
private int _bitW ;
private int _bitH ;
public void StartOffScreenBitmap ( int width , int height )
{
_bitW = width ;
_bitH = height ;
_bitHDC = CreateCompatibleDC ( _hdc ) ;
_bitMap = CreateCompatibleBitmap ( _hdc , width , height ) ;
2014-08-18 00:48:11 +00:00
SelectObject ( _bitHDC , _bitMap ) ;
2014-08-18 06:50:12 +00:00
SetBkMode ( _bitHDC , BkModes . TRANSPARENT ) ;
2014-08-18 00:23:09 +00:00
}
public void EndOffScreenBitmap ( )
{
_bitW = 0 ;
_bitH = 0 ;
DeleteObject ( _bitMap ) ;
DeleteObject ( _bitHDC ) ;
_bitHDC = IntPtr . Zero ;
_bitMap = IntPtr . Zero ;
}
public void CopyToScreen ( )
{
2014-08-18 00:48:11 +00:00
BitBlt ( _hdc , 0 , 0 , _bitW , _bitH , _bitHDC , 0 , 0 , 0x00CC0020 ) ;
2014-08-08 02:09:59 +00:00
}
2014-08-10 22:23:14 +00:00
#endregion
2014-08-07 23:10:41 +00:00
2014-08-10 22:23:14 +00:00
#region Helpers
2014-08-07 23:10:41 +00:00
2014-08-10 22:23:14 +00:00
/// <summary>
/// Set a resource (e.g. a font) for the specified device context.
/// </summary>
private void SetFont ( Font font )
2014-08-07 23:10:41 +00:00
{
2014-08-10 22:23:14 +00:00
SelectObject ( _hdc , GetCachedHFont ( font ) ) ;
2014-08-07 23:10:41 +00:00
}
2015-07-07 19:05:05 +00:00
private IntPtr GetCachedHFont ( Font font )
2014-08-08 02:09:59 +00:00
{
2014-10-22 07:59:06 +00:00
//the original code struck me as bad. attempting to ID fonts by picking a subset of their fields is not gonna work.
//don't call this.Font in InputRoll.cs, it is probably slow.
//consider Fonts to be a jealously guarded resource (they need to be disposed, after all) and manage them carefully.
//this cache maintains the HFONTs only.
FontCacheEntry ce ;
if ( ! FontsCache . TryGetValue ( font , out ce ) )
2014-08-10 22:23:14 +00:00
{
2014-10-22 07:59:06 +00:00
FontsCache [ font ] = ce = new FontCacheEntry ( ) ;
ce . HFont = font . ToHfont ( ) ;
2014-08-10 22:23:14 +00:00
}
2014-10-22 07:59:06 +00:00
return ce . HFont ;
2014-08-08 02:09:59 +00:00
}
2014-08-07 23:10:41 +00:00
#endregion
#region Imports
[DllImport("user32.dll")]
private static extern int ReleaseDC ( IntPtr hWnd , IntPtr hDC ) ;
[DllImport("user32.dll")]
private static extern IntPtr GetDC ( IntPtr hWnd ) ;
2014-08-10 14:25:59 +00:00
[DllImport("user32.dll")]
private static extern IntPtr BeginPaint ( IntPtr hWnd , ref IntPtr lpPaint ) ;
[DllImport("user32.dll")]
private static extern IntPtr EndPaint ( IntPtr hWnd , IntPtr lpPaint ) ;
2014-10-22 07:59:06 +00:00
[DllImport("gdi32.dll")]
static extern IntPtr CreateFontIndirect ( [ In ] ref LOGFONT lplf ) ;
2014-08-07 23:10:41 +00:00
[DllImport("gdi32.dll")]
private static extern int Rectangle ( IntPtr hdc , int nLeftRect , int nTopRect , int nRightRect , int nBottomRect ) ;
2014-08-07 23:52:19 +00:00
[DllImport("user32.dll")]
2014-08-10 22:23:14 +00:00
private static extern int FillRect ( IntPtr hdc , [ In ] ref GDIRect lprc , IntPtr hbr ) ;
2014-08-05 01:03:16 +00:00
2014-08-05 00:18:55 +00:00
[DllImport("gdi32.dll")]
2014-08-18 06:50:12 +00:00
private static extern int SetBkMode ( IntPtr hdc , BkModes mode ) ;
2014-08-05 00:18:55 +00:00
[DllImport("gdi32.dll")]
2014-10-22 07:59:06 +00:00
private static extern IntPtr SelectObject ( IntPtr hdc , IntPtr hgdiObj ) ;
2014-08-05 00:18:55 +00:00
[DllImport("gdi32.dll")]
private static extern int SetTextColor ( IntPtr hdc , int color ) ;
2014-08-07 23:10:41 +00:00
[DllImport("gdi32.dll")]
private static extern int SetBkColor ( IntPtr hdc , int color ) ;
2014-08-05 00:18:55 +00:00
[DllImport("gdi32.dll", EntryPoint = "GetTextExtentPoint32W")]
private static extern int GetTextExtentPoint32 ( IntPtr hdc , [ MarshalAs ( UnmanagedType . LPWStr ) ] string str , int len , ref Size size ) ;
[DllImport("gdi32.dll", EntryPoint = "GetTextExtentExPointW")]
private static extern bool GetTextExtentExPoint ( IntPtr hDc , [ MarshalAs ( UnmanagedType . LPWStr ) ] string str , int nLength , int nMaxExtent , int [ ] lpnFit , int [ ] alpDx , ref Size size ) ;
[DllImport("gdi32.dll", EntryPoint = "TextOutW")]
private static extern bool TextOut ( IntPtr hdc , int x , int y , [ MarshalAs ( UnmanagedType . LPWStr ) ] string str , int len ) ;
2014-10-22 07:59:06 +00:00
[DllImport("gdi32.dll")]
public static extern int SetGraphicsMode ( IntPtr hdc , int iMode ) ;
2014-08-05 00:18:55 +00:00
[DllImport("user32.dll", EntryPoint = "DrawTextW")]
private static extern int DrawText ( IntPtr hdc , [ MarshalAs ( UnmanagedType . LPWStr ) ] string str , int len , ref Rect rect , uint uFormat ) ;
2014-10-22 07:59:06 +00:00
[DllImport("gdi32.dll", EntryPoint = "ExtTextOutW")]
private static extern bool ExtTextOut ( IntPtr hdc , int X , int Y , uint fuOptions , uint cbCount , [ In ] IntPtr lpDx ) ;
[DllImport("gdi32.dll")]
static extern bool SetWorldTransform ( IntPtr hdc , [ In ] ref XFORM lpXform ) ;
2014-08-05 00:18:55 +00:00
[DllImport("gdi32.dll")]
private static extern int SelectClipRgn ( IntPtr hdc , IntPtr hrgn ) ;
[DllImport("gdi32.dll")]
private static extern bool DeleteObject ( IntPtr hObject ) ;
2014-08-07 23:10:41 +00:00
[DllImport("gdi32.dll")]
private static extern IntPtr CreateSolidBrush ( int color ) ;
2014-08-05 00:18:55 +00:00
2014-08-09 16:11:25 +00:00
[DllImport("gdi32.dll")]
private static extern IntPtr CreatePen ( int fnPenStyle , int nWidth , int color ) ;
2014-08-08 02:09:59 +00:00
[DllImport("gdi32.dll")]
private static extern IntPtr MoveToEx ( IntPtr hdc , int x , int y , IntPtr point ) ;
[DllImport("gdi32.dll")]
private static extern IntPtr LineTo ( IntPtr hdc , int nXEnd , int nYEnd ) ;
2014-08-09 16:11:25 +00:00
[DllImport("gdi32.dll")]
private static extern IntPtr GetStockObject ( int fnObject ) ;
[DllImport("gdi32.dll")]
private static extern IntPtr SetDCPenColor ( IntPtr hdc , int crColor ) ;
2014-08-18 00:23:09 +00:00
[DllImport("gdi32.dll")]
private static extern IntPtr CreateCompatibleDC ( IntPtr hdc ) ;
2014-09-03 02:52:46 +00:00
[DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
public static extern bool DeleteDC ( [ In ] IntPtr hdc ) ;
2014-08-18 00:23:09 +00:00
[DllImport("gdi32.dll")]
private static extern IntPtr CreateCompatibleBitmap ( IntPtr hdc , int width , int height ) ;
2014-08-18 00:48:11 +00:00
[DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool BitBlt ( [ In ] IntPtr hdc , int nXDest , int nYDest , int nWidth , int nHeight , [ In ] IntPtr hdcSrc , int nXSrc , int nYSrc , int dwRop ) ;
2014-08-18 00:23:09 +00:00
2014-09-18 00:31:32 +00:00
[DllImport("gdi32.dll", EntryPoint = "GdiAlphaBlend")]
static extern bool AlphaBlend ( IntPtr hdcDest , int nXOriginDest , int nYOriginDest , int nWidthDest , int nHeightDest , IntPtr hdcSrc , int nXOriginSrc , int nYOriginSrc , int nWidthSrc , int nHeightSrc , BLENDFUNCTION blendFunction ) ;
2014-10-22 07:59:06 +00:00
public enum FontWeight : int
{
FW_DONTCARE = 0 ,
FW_THIN = 100 ,
FW_EXTRALIGHT = 200 ,
FW_LIGHT = 300 ,
FW_NORMAL = 400 ,
FW_MEDIUM = 500 ,
FW_SEMIBOLD = 600 ,
FW_BOLD = 700 ,
FW_EXTRABOLD = 800 ,
FW_HEAVY = 900 ,
}
public enum FontCharSet : byte
{
ANSI_CHARSET = 0 ,
DEFAULT_CHARSET = 1 ,
SYMBOL_CHARSET = 2 ,
SHIFTJIS_CHARSET = 128 ,
HANGEUL_CHARSET = 129 ,
HANGUL_CHARSET = 129 ,
GB2312_CHARSET = 134 ,
CHINESEBIG5_CHARSET = 136 ,
OEM_CHARSET = 255 ,
JOHAB_CHARSET = 130 ,
HEBREW_CHARSET = 177 ,
ARABIC_CHARSET = 178 ,
GREEK_CHARSET = 161 ,
TURKISH_CHARSET = 162 ,
VIETNAMESE_CHARSET = 163 ,
THAI_CHARSET = 222 ,
EASTEUROPE_CHARSET = 238 ,
RUSSIAN_CHARSET = 204 ,
MAC_CHARSET = 77 ,
BALTIC_CHARSET = 186 ,
}
public enum FontPrecision : byte
{
OUT_DEFAULT_PRECIS = 0 ,
OUT_STRING_PRECIS = 1 ,
OUT_CHARACTER_PRECIS = 2 ,
OUT_STROKE_PRECIS = 3 ,
OUT_TT_PRECIS = 4 ,
OUT_DEVICE_PRECIS = 5 ,
OUT_RASTER_PRECIS = 6 ,
OUT_TT_ONLY_PRECIS = 7 ,
OUT_OUTLINE_PRECIS = 8 ,
OUT_SCREEN_OUTLINE_PRECIS = 9 ,
OUT_PS_ONLY_PRECIS = 10 ,
}
public enum FontClipPrecision : byte
{
CLIP_DEFAULT_PRECIS = 0 ,
CLIP_CHARACTER_PRECIS = 1 ,
CLIP_STROKE_PRECIS = 2 ,
CLIP_MASK = 0xf ,
CLIP_LH_ANGLES = ( 1 < < 4 ) ,
CLIP_TT_ALWAYS = ( 2 < < 4 ) ,
CLIP_DFA_DISABLE = ( 4 < < 4 ) ,
CLIP_EMBEDDED = ( 8 < < 4 ) ,
}
public enum FontQuality : byte
{
DEFAULT_QUALITY = 0 ,
DRAFT_QUALITY = 1 ,
PROOF_QUALITY = 2 ,
NONANTIALIASED_QUALITY = 3 ,
ANTIALIASED_QUALITY = 4 ,
CLEARTYPE_QUALITY = 5 ,
CLEARTYPE_NATURAL_QUALITY = 6 ,
}
[Flags]
public enum FontPitchAndFamily : byte
{
DEFAULT_PITCH = 0 ,
FIXED_PITCH = 1 ,
VARIABLE_PITCH = 2 ,
FF_DONTCARE = ( 0 < < 4 ) ,
FF_ROMAN = ( 1 < < 4 ) ,
FF_SWISS = ( 2 < < 4 ) ,
FF_MODERN = ( 3 < < 4 ) ,
FF_SCRIPT = ( 4 < < 4 ) ,
FF_DECORATIVE = ( 5 < < 4 ) ,
}
//it is important for this to be the right declaration
//see more here http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.drawing/2004-04/0319.html
//if it's wrong (I had a wrong one from pinvoke.net) then ToLogFont will fail mysteriously
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
class LOGFONT
{
public int lfHeight = 0 ;
public int lfWidth = 0 ;
public int lfEscapement = 0 ;
public int lfOrientation = 0 ;
public int lfWeight = 0 ;
public byte lfItalic = 0 ;
public byte lfUnderline = 0 ;
public byte lfStrikeOut = 0 ;
public byte lfCharSet = 0 ;
public byte lfOutPrecision = 0 ;
public byte lfClipPrecision = 0 ;
public byte lfQuality = 0 ;
public byte lfPitchAndFamily = 0 ;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string lfFaceName = null ;
}
/// <summary>
/// The graphics mode that can be set by SetGraphicsMode.
/// </summary>
public enum GraphicsMode : int
{
/// <summary>
/// Sets the graphics mode that is compatible with 16-bit Windows. This is the default mode. If
/// this value is specified, the application can only modify the world-to-device transform by
/// calling functions that set window and viewport extents and origins, but not by using
/// SetWorldTransform or ModifyWorldTransform; calls to those functions will fail.
/// Examples of functions that set window and viewport extents and origins are SetViewportExtEx
/// and SetWindowExtEx.
/// </summary>
GM_COMPATIBLE = 1 ,
/// <summary>
/// Sets the advanced graphics mode that allows world transformations. This value must be
/// specified if the application will set or modify the world transformation for the specified
/// device context. In this mode all graphics, including text output, fully conform to the
/// world-to-device transformation specified in the device context.
/// </summary>
GM_ADVANCED = 2 ,
}
/// <summary>
/// The XFORM structure specifies a world-space to page-space transformation.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct XFORM
{
public float eM11 ;
public float eM12 ;
public float eM21 ;
public float eM22 ;
public float eDx ;
public float eDy ;
public XFORM ( float eM11 , float eM12 , float eM21 , float eM22 , float eDx , float eDy )
{
this . eM11 = eM11 ;
this . eM12 = eM12 ;
this . eM21 = eM21 ;
this . eM22 = eM22 ;
this . eDx = eDx ;
this . eDy = eDy ;
}
/// <summary>
/// Allows implicit converstion to a managed transformation matrix.
/// </summary>
public static implicit operator System . Drawing . Drawing2D . Matrix ( XFORM xf )
{
return new System . Drawing . Drawing2D . Matrix ( xf . eM11 , xf . eM12 , xf . eM21 , xf . eM22 , xf . eDx , xf . eDy ) ;
}
/// <summary>
/// Allows implicit converstion from a managed transformation matrix.
/// </summary>
public static implicit operator XFORM ( System . Drawing . Drawing2D . Matrix m )
{
float [ ] elems = m . Elements ;
return new XFORM ( elems [ 0 ] , elems [ 1 ] , elems [ 2 ] , elems [ 3 ] , elems [ 4 ] , elems [ 5 ] ) ;
}
}
2014-09-18 00:31:32 +00:00
[StructLayout(LayoutKind.Sequential)]
public struct BLENDFUNCTION
{
byte BlendOp ;
byte BlendFlags ;
byte SourceConstantAlpha ;
byte AlphaFormat ;
public BLENDFUNCTION ( byte op , byte flags , byte alpha , byte format )
{
BlendOp = op ;
BlendFlags = flags ;
SourceConstantAlpha = alpha ;
AlphaFormat = format ;
}
}
const byte AC_SRC_OVER = 0x00 ;
const byte AC_SRC_ALPHA = 0x01 ;
2014-09-03 02:24:13 +00:00
[DllImport("gdi32.dll")]
static extern int SetBitmapBits ( IntPtr hbmp , uint cBytes , byte [ ] lpBits ) ;
2014-08-05 00:18:55 +00:00
#endregion
2014-08-10 22:23:14 +00:00
#region Classes , Structs , and Enums
2014-08-09 16:11:25 +00:00
2014-08-10 22:23:14 +00:00
public class GdiGraphicsLock : IDisposable
{
private readonly GDIRenderer Gdi ;
2014-08-09 16:11:25 +00:00
2014-08-10 22:23:14 +00:00
public GdiGraphicsLock ( GDIRenderer gdi )
{
this . Gdi = gdi ;
}
2014-08-09 16:50:38 +00:00
2014-08-10 22:23:14 +00:00
public void Dispose ( )
{
Gdi . _g . ReleaseHdc ( Gdi . _hdc ) ;
Gdi . _hdc = IntPtr . Zero ;
Gdi . _g = null ;
}
}
private struct Rect
{
private int _left ;
private int _top ;
private int _right ;
private int _bottom ;
public Rect ( Rectangle r )
{
_left = r . Left ;
_top = r . Top ;
_bottom = r . Bottom ;
_right = r . Right ;
}
}
private struct GDIRect
{
private int left ;
private int top ;
private int right ;
private int bottom ;
public GDIRect ( Rectangle r )
{
left = r . Left ;
top = r . Top ;
bottom = r . Bottom ;
right = r . Right ;
}
}
private struct GDIPoint
{
private int x ;
private int y ;
private GDIPoint ( int x , int y )
{
this . x = x ;
this . y = y ;
}
}
2014-10-22 07:59:06 +00:00
[Flags]
public enum ETOOptions : uint
{
CLIPPED = 0x4 ,
GLYPH_INDEX = 0x10 ,
IGNORELANGUAGE = 0x1000 ,
NUMERICSLATIN = 0x800 ,
NUMERICSLOCAL = 0x400 ,
OPAQUE = 0x2 ,
PDY = 0x2000 ,
RTLREADING = 0x800 ,
}
2014-08-10 22:23:14 +00:00
/// <summary>
/// See [http://msdn.microsoft.com/en-us/library/windows/desktop/dd162498(v=vs.85).aspx][15]
/// </summary>
[Flags]
public enum TextFormatFlags : uint
{
Default = 0x00000000 ,
Center = 0x00000001 ,
Right = 0x00000002 ,
VCenter = 0x00000004 ,
Bottom = 0x00000008 ,
WordBreak = 0x00000010 ,
SingleLine = 0x00000020 ,
ExpandTabs = 0x00000040 ,
TabStop = 0x00000080 ,
NoClip = 0x00000100 ,
ExternalLeading = 0x00000200 ,
CalcRect = 0x00000400 ,
NoPrefix = 0x00000800 ,
Internal = 0x00001000 ,
EditControl = 0x00002000 ,
PathEllipsis = 0x00004000 ,
EndEllipsis = 0x00008000 ,
ModifyString = 0x00010000 ,
RtlReading = 0x00020000 ,
WordEllipsis = 0x00040000 ,
NoFullWidthCharBreak = 0x00080000 ,
HidePrefix = 0x00100000 ,
ProfixOnly = 0x00200000 ,
}
[Flags]
public enum PenStyles
{
PS_SOLID = 0x00000000
// TODO
}
public enum PaintObjects
{
WHITE_BRUSH = 0 ,
LTGRAY_BRUSH = 1 ,
GRAY_BRUSH = 2 ,
DKGRAY_BRUSH = 3 ,
BLACK_BRUSH = 4 ,
NULL_BRUSH = 5 ,
WHITE_PEN = 6 ,
BLACK_PEN = 7 ,
NULL_PEN = 8 ,
OEM_FIXED_FONT = 10 ,
ANSI_FIXED_FONT = 11 ,
ANSI_VAR_FONT = 12 ,
SYSTEM_FONT = 13 ,
DEVICE_DEFAULT_FONT = 14 ,
DEFAULT_PALETTE = 15 ,
SYSTEM_FIXED_FONT = 16 ,
DC_BRUSH = 18 ,
DC_PEN = 19 ,
}
2014-08-18 06:50:12 +00:00
public enum BkModes : int
2014-08-10 22:23:14 +00:00
{
TRANSPARENT = 1 ,
OPAQUE = 2
}
#endregion
2014-08-09 16:50:38 +00:00
}
2014-08-05 00:18:55 +00:00
}