using System;
using System.Drawing;
using System.Windows.Forms;
using Storm.TextEditor.Win32;
using Storm.TextEditor.Win32.Enums;
using Storm.TextEditor.Win32.Structs;
namespace Storm.TextEditor.Drawing.GDI
{
public class GDISurface
: GDIObject
{
#region Fields
protected int width = 0;
protected int height = 0;
protected int tabSize = 4;
protected IntPtr oldFont = IntPtr.Zero;
protected IntPtr oldPen = IntPtr.Zero;
protected IntPtr oldBrush = IntPtr.Zero;
protected IntPtr oldBmp = IntPtr.Zero;
protected IntPtr hDC = IntPtr.Zero;
protected IntPtr hBMP = IntPtr.Zero;
private WeakReference control = null;
#endregion
#region Properties
private Control Control
{
get
{
if (control != null)
return (Control)control.Target;
else
return null;
}
set { control = new WeakReference(value); }
}
public GDIFont Font
{
get
{
GDITextMetric tm = new GDITextMetric();
string fontname = " ";
NativeGdi32Api.GetTextMetrics(hDC, ref tm);
NativeGdi32Api.GetTextFace(hDC, 79, fontname);
GDIFont gf = new GDIFont();
gf.fontname = fontname;
gf.bold = (tm.tmWeight > 400);
gf.italic = (tm.tmItalic != 0);
gf.underline = (tm.tmUnderlined != 0);
gf.strikethrough = (tm.tmStruckOut != 0);
gf.size = (int)(((double)(tm.tmMemoryHeight) / (double)tm.tmDigitizedAspectY) * 72);
return gf;
}
set
{
IntPtr res = NativeGdi32Api.SelectObject(hDC, value.hFont);
if (oldFont == IntPtr.Zero)
oldFont = res;
}
}
public IntPtr HDC
{
get { return hDC; }
}
public IntPtr HBMP
{
get { return hBMP; }
}
public Color TextForeColor
{
get { return NativeUser32Api.IntToColor(NativeGdi32Api.GetTextColor(hDC)); }
set { NativeGdi32Api.SetTextColor(hDC, NativeUser32Api.ColorToInt(value)); }
}
public Color TextBackColor
{
get { return NativeUser32Api.IntToColor(NativeGdi32Api.GetBkColor(hDC)); }
set { NativeGdi32Api.SetBkColor(hDC, NativeUser32Api.ColorToInt(value)); }
}
public bool FontTransparent
{
get { return NativeGdi32Api.GetBkMode(hDC) < 2; }
set { NativeGdi32Api.SetBkMode(hDC, value ? 1 : 2); }
}
#endregion
#region Methods
#region Protected
protected void Init(int width, int height, IntPtr hdc)
{
this.width = width;
this.height = height;
hDC = NativeGdi32Api.CreateCompatibleDC(hdc);
hBMP = NativeGdi32Api.CreateCompatibleBitmap(hdc, width, height);
IntPtr ret = NativeGdi32Api.SelectObject(hDC, hBMP);
oldBmp = ret;
if (hDC == (IntPtr)0)
throw new Exception("Creation of hDC failed.");
if (hDC == (IntPtr)0)
throw new Exception("Creation of hBMP failed.");
}
protected override void Destroy()
{
if (oldBmp != IntPtr.Zero)
NativeGdi32Api.SelectObject(hDC, oldBmp);
if (oldFont != IntPtr.Zero)
NativeGdi32Api.SelectObject(hDC, oldFont);
if (oldPen != IntPtr.Zero)
NativeGdi32Api.SelectObject(hDC, oldPen);
if (oldBrush != IntPtr.Zero)
NativeGdi32Api.SelectObject(hDC, oldBrush);
if (hBMP != (IntPtr)0)
NativeGdi32Api.DeleteObject(hBMP);
if (hDC != (IntPtr)0)
NativeGdi32Api.DeleteDC(hDC);
hBMP = (IntPtr)0;
hDC = (IntPtr)0;
base.Destroy();
}
#endregion
#region Public
public Size MeasureTabbedString(string text, int tabSize)
{
uint ret = NativeUser32Api.GetTabbedTextExtent(hDC, text, text.Length, 1, ref tabSize);
return new Size((int)(ret & 0xFFFF), (int)((ret >> 16) & 0xFFFF));
}
public Size DrawTabbedString(string text, int x, int y, int tabOrigin, int tabSize)
{
int ret = NativeUser32Api.TabbedTextOut(hDC, x, y, text, text.Length, 2, ref tabSize, tabOrigin);
return new Size(ret & 0xFFFF, (ret >> 16) & 0xFFFF);
}
public void RenderTo(IntPtr hdc, int x, int y)
{
NativeGdi32Api.BitBlt(hdc, x, y, width, height, hDC, 0, 0, (int)GDIRop.SrcCopy);
}
public void RenderTo(GDISurface target, int x, int y)
{
this.RenderTo(target.hDC, x, y);
}
public void RenderTo(GDISurface target, int sourceX, int sourceY, int width, int height, int destX, int destY)
{
NativeGdi32Api.BitBlt(target.hDC, destX, destY, width, height, hDC, sourceX, sourceY, (int)GDIRop.SrcCopy);
}
public void RenderToControl(int x, int y)
{
IntPtr hdc = NativeUser32Api.ControlDC(this.Control);
this.RenderTo(hdc, x, y);
NativeUser32Api.ReleaseDC(this.Control.Handle, hdc);
}
public Graphics CreateGraphics()
{
return Graphics.FromHdc(hDC);
}
public void FillRect(GDIBrush brush, int x, int y, int width, int height)
{
RECTAPI gr;
gr.Top = y;
gr.Left = x;
gr.Right = width + x;
gr.Bottom = height + y;
NativeUser32Api.FillRect(hDC, ref gr, brush.brush);
}
public void DrawFocusRect(int x, int y, int width, int height)
{
RECTAPI gr;
gr.Top = y;
gr.Left = x;
gr.Right = width + x;
gr.Bottom = height + y;
NativeUser32Api.DrawFocusRect(hDC, ref gr);
}
public void FillRect(Color color, int x, int y, int width, int height)
{
GDIBrush b = new GDIBrush(color);
this.FillRect(b, x, y, width, height);
b.Dispose();
}
public void InvertRect(int x, int y, int width, int height)
{
RECTAPI gr;
gr.Top = y;
gr.Left = x;
gr.Right = width + x;
gr.Bottom = height + y;
NativeUser32Api.InvertRect(hDC, ref gr);
}
public void DrawLine(GDIPen pen, Point p1, Point p2)
{
IntPtr oldpen = NativeGdi32Api.SelectObject(hDC, pen.hPen);
POINTAPI gp;
gp.X = 0;
gp.Y = 0;
NativeGdi32Api.MoveToEx(hDC, p1.X, p1.Y, ref gp);
NativeGdi32Api.LineTo(hDC, p2.X, p2.Y);
IntPtr crap = NativeGdi32Api.SelectObject(hDC, oldpen);
}
public void DrawLine(Color color, Point p1, Point p2)
{
GDIPen p = new GDIPen(color, 1);
this.DrawLine(p, p1, p2);
p.Dispose();
}
public void DrawRect(Color color, int left, int top, int width, int height)
{
GDIPen p = new GDIPen(color, 1);
this.DrawRect(p, left, top, width, height);
p.Dispose();
}
public void DrawRect(GDIPen pen, int left, int top, int width, int height)
{
this.DrawLine(pen, new Point(left, top), new Point(left + width, top));
this.DrawLine(pen, new Point(left, top + height), new Point(left + width, top + height));
this.DrawLine(pen, new Point(left, top), new Point(left, top + height));
this.DrawLine(pen, new Point(left + width, top), new Point(left + width, top + height + 1));
}
public void Clear(Color color)
{
GDIBrush b = new GDIBrush(color);
this.Clear(b);
b.Dispose();
}
public void Clear(GDIBrush brush)
{
this.FillRect(brush, 0, 0, width, height);
}
public void Flush()
{
NativeGdi32Api.GdiFlush();
}
public void SetBrushOrg(int x, int y)
{
POINTAPI p;
p.X = 0;
p.Y = 0;
NativeGdi32Api.SetBrushOrgEx(hDC, x, y, ref p);
}
#endregion
#endregion
/// <summary>
/// Initializes a new instance of GDISurface.
/// </summary>
public GDISurface(IntPtr hDC)
{
this.hDC = hDC;
}
/// <summary>
/// Initializes a new instance of GDISurface.
/// </summary>
public GDISurface(int width, int height)
{
IntPtr deskDC = NativeUser32Api.GetDC(new IntPtr(0));
this.Init(width, height, deskDC);
this.Create();
}
/// <summary>
/// Initializes a new instance of GDISurface.
/// </summary>
public GDISurface(int width, int height, IntPtr hdc)
{
this.Init(width, height, hdc);
this.Create();
}
/// <summary>
/// Initializes a new instance of GDISurface.
/// </summary>
public GDISurface(int width, int height, GDISurface surface)
{
this.Init(width, height, surface.hDC);
this.Create();
}
/// <summary>
/// Initializes a new instance of GDISurface.
/// </summary>
public GDISurface(int width, int height, Control compatibleControl, bool bindControl)
{
IntPtr hDCControk = NativeUser32Api.ControlDC(compatibleControl);
this.Init(width, height, hDCControk);
NativeUser32Api.ReleaseDC(compatibleControl.Handle, hDCControk);
if (bindControl)
this.Control = compatibleControl;
this.Create();
}
}
}