using System;
//using System.Drawing;
using System.IO;
namespace Gwen.Renderer
{
///
/// Base renderer.
///
public class Base : IDisposable
{
//public Random rnd;
private Point m_RenderOffset;
private Rectangle m_ClipRegion;
//protected ICacheToTexture m_RTT;
public float Scale { get; set; }
///
/// Initializes a new instance of the class.
///
protected Base()
{
//rnd = new Random();
m_RenderOffset = Point.Empty;
Scale = 1.0f;
if (CTT != null)
CTT.Initialize();
}
///
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
///
/// 2
public virtual void Dispose()
{
if (CTT != null)
CTT.ShutDown();
GC.SuppressFinalize(this);
}
#if DEBUG
~Base()
{
throw new InvalidOperationException(String.Format("IDisposable object finalized: {0}", GetType()));
//Debug.Print(String.Format("IDisposable object finalized: {0}", GetType()));
}
#endif
///
/// Starts rendering.
///
public virtual void Begin()
{}
///
/// Stops rendering.
///
public virtual void End()
{}
///
/// Gets or sets the current drawing color.
///
public virtual Color DrawColor { get; set; }
///
/// Rendering offset. No need to touch it usually.
///
public Point RenderOffset { get { return m_RenderOffset; } set { m_RenderOffset = value; } }
///
/// Clipping rectangle.
///
public Rectangle ClipRegion { get { return m_ClipRegion; } set { m_ClipRegion = value; } }
///
/// Indicates whether the clip region is visible.
///
public bool ClipRegionVisible
{
get
{
if (m_ClipRegion.Width <= 0 || m_ClipRegion.Height <= 0)
return false;
return true;
}
}
///
/// Draws a line.
///
///
///
///
///
public virtual void DrawLine(int x, int y, int a, int b)
{}
///
/// Draws a solid filled rectangle.
///
///
public virtual void DrawFilledRect(Rectangle rect)
{}
///
/// Starts clipping to the current clipping rectangle.
///
public virtual void StartClip()
{}
///
/// Stops clipping.
///
public virtual void EndClip()
{}
///
/// Loads the specified texture.
///
///
public virtual void LoadTexture(Texture t)
{}
///
/// Initializes texture from raw pixel data.
///
/// Texture to initialize. Dimensions need to be set.
/// Pixel data in RGBA format.
public virtual void LoadTextureRaw(Texture t, byte[] pixelData)
{}
///
/// Initializes texture from image file data.
///
/// Texture to initialize.
/// Image file as stream.
public virtual void LoadTextureStream(Texture t, Stream data)
{}
///
/// Frees the specified texture.
///
/// Texture to free.
public virtual void FreeTexture(Texture t)
{}
///
/// Draws textured rectangle.
///
/// Texture to use.
/// Rectangle bounds.
/// Texture coordinate u1.
/// Texture coordinate v1.
/// Texture coordinate u2.
/// Texture coordinate v2.
public virtual void DrawTexturedRect(Texture t, Rectangle targetRect, float u1=0, float v1=0, float u2=1, float v2=1)
{}
///
/// Draws "missing image" default texture.
///
/// Target rectangle.
public virtual void DrawMissingImage(Rectangle rect)
{
//DrawColor = Color.FromArgb(255, rnd.Next(0,255), rnd.Next(0,255), rnd.Next(0, 255));
DrawColor = Color.Red;
DrawFilledRect(rect);
}
///
/// Cache to texture provider.
///
public virtual ICacheToTexture CTT { get { return null; } }
///
/// Loads the specified font.
///
/// Font to load.
/// True if succeeded.
public virtual bool LoadFont(Font font)
{
return false;
}
///
/// Frees the specified font.
///
/// Font to free.
public virtual void FreeFont(Font font)
{}
///
/// Returns dimensions of the text using specified font.
///
/// Font to use.
/// Text to measure.
/// Width and height of the rendered text.
public virtual Point MeasureText(Font font, String text)
{
Point p = new Point((int)(font.Size * Scale * text.Length * 0.4f), (int)(font.Size * Scale));
return p;
}
///
/// Renders text using specified font.
///
/// Font to use.
/// Top-left corner of the text.
/// Text to render.
public virtual void RenderText(Font font, Point position, String text)
{
float size = font.Size * Scale;
for ( int i=0; i= 'a' && chr <= 'z' )
{
r.Y = (int)(r.Y + size * 0.5f);
r.Height = (int)(r.Height - size * 0.4f);
}
else if ( chr == '.' || chr == ',' )
{
r.X += 2;
r.Y += r.Height - 2;
r.Width = 2;
r.Height = 2;
}
else if ( chr == '\'' || chr == '`' || chr == '"' )
{
r.X += 3;
r.Width = 2;
r.Height = 2;
}
if ( chr == 'o' || chr == 'O' || chr == '0' )
DrawLinedRect( r );
else
DrawFilledRect( r );
}
}
//
// No need to implement these functions in your derived class, but if
// you can do them faster than the default implementation it's a good idea to.
//
///
/// Draws a lined rectangle. Used for keyboard focus overlay.
///
/// Target rectangle.
public virtual void DrawLinedRect(Rectangle rect)
{
DrawFilledRect(new Rectangle(rect.X, rect.Y, rect.Width, 1));
DrawFilledRect(new Rectangle(rect.X, rect.Y + rect.Height - 1, rect.Width, 1));
DrawFilledRect(new Rectangle(rect.X, rect.Y, 1, rect.Height));
DrawFilledRect(new Rectangle(rect.X + rect.Width - 1, rect.Y, 1, rect.Height));
}
///
/// Draws a single pixel. Very slow, do not use. :P
///
/// X.
/// Y.
public virtual void DrawPixel(int x, int y)
{
// [omeg] amazing ;)
DrawFilledRect(new Rectangle(x, y, 1, 1));
}
///
/// Gets pixel color of a specified texture. Slow.
///
/// Texture.
/// X.
/// Y.
/// Pixel color.
public virtual Color PixelColor(Texture texture, uint x, uint y)
{
return PixelColor(texture, x, y, Color.White);
}
///
/// Gets pixel color of a specified texture, returning default if otherwise failed. Slow.
///
/// Texture.
/// X.
/// Y.
/// Color to return on failure.
/// Pixel color.
public virtual Color PixelColor(Texture texture, uint x, uint y, Color defaultColor)
{
return defaultColor;
}
///
/// Draws a round-corner rectangle.
///
/// Target rectangle.
///
public virtual void DrawShavedCornerRect(Rectangle rect, bool slight = false)
{
// Draw INSIDE the w/h.
rect.Width -= 1;
rect.Height -= 1;
if (slight)
{
DrawFilledRect(new Rectangle(rect.X + 1, rect.Y, rect.Width - 1, 1));
DrawFilledRect(new Rectangle(rect.X + 1, rect.Y + rect.Height, rect.Width - 1, 1));
DrawFilledRect(new Rectangle(rect.X, rect.Y + 1, 1, rect.Height - 1));
DrawFilledRect(new Rectangle(rect.X + rect.Width, rect.Y + 1, 1, rect.Height - 1));
return;
}
DrawPixel(rect.X + 1, rect.Y + 1);
DrawPixel(rect.X + rect.Width - 1, rect.Y + 1);
DrawPixel(rect.X + 1, rect.Y + rect.Height - 1);
DrawPixel(rect.X + rect.Width - 1, rect.Y + rect.Height - 1);
DrawFilledRect(new Rectangle(rect.X + 2, rect.Y, rect.Width - 3, 1));
DrawFilledRect(new Rectangle(rect.X + 2, rect.Y + rect.Height, rect.Width - 3, 1));
DrawFilledRect(new Rectangle(rect.X, rect.Y + 2, 1, rect.Height - 3));
DrawFilledRect(new Rectangle(rect.X + rect.Width, rect.Y + 2, 1, rect.Height - 3));
}
private int TranslateX(int x)
{
int x1 = x + m_RenderOffset.X;
return Util.Ceil(x1 * Scale);
}
private int TranslateY(int y)
{
int y1 = y + m_RenderOffset.Y;
return Util.Ceil(y1 * Scale);
}
///
/// Translates a panel's local drawing coordinate into view space, taking offsets into account.
///
///
///
public void Translate(ref int x, ref int y)
{
x += m_RenderOffset.X;
y += m_RenderOffset.Y;
x = Util.Ceil(x * Scale);
y = Util.Ceil(y * Scale);
}
///
/// Translates a panel's local drawing coordinate into view space, taking offsets into account.
///
public Point Translate(Point p)
{
int x = p.X;
int y = p.Y;
Translate(ref x, ref y);
return new Point(x, y);
}
///
/// Translates a panel's local drawing coordinate into view space, taking offsets into account.
///
public Rectangle Translate(Rectangle rect)
{
return new Rectangle(TranslateX(rect.X), TranslateY(rect.Y), Util.Ceil(rect.Width * Scale), Util.Ceil(rect.Height * Scale));
}
///
/// Adds a point to the render offset.
///
/// Point to add.
public void AddRenderOffset(Rectangle offset)
{
m_RenderOffset = new Point(m_RenderOffset.X + offset.X, m_RenderOffset.Y + offset.Y);
}
///
/// Adds a rectangle to the clipping region.
///
/// Rectangle to add.
public void AddClipRegion(Rectangle rect)
{
rect.X = m_RenderOffset.X;
rect.Y = m_RenderOffset.Y;
Rectangle r = rect;
if (rect.X < m_ClipRegion.X)
{
r.Width -= (m_ClipRegion.X - r.X);
r.X = m_ClipRegion.X;
}
if (rect.Y < m_ClipRegion.Y)
{
r.Height -= (m_ClipRegion.Y - r.Y);
r.Y = m_ClipRegion.Y;
}
if (rect.Right > m_ClipRegion.Right)
{
r.Width = m_ClipRegion.Right - r.X;
}
if (rect.Bottom > m_ClipRegion.Bottom)
{
r.Height = m_ClipRegion.Bottom - r.Y;
}
m_ClipRegion = r;
}
}
}