This repository has been archived on 2025-01-01. You can view files and clone it, but cannot push or open issues or pull requests.
ShiftOS_TheReturn/ShiftOS.Frontend/GraphicsSubsystem/GraphicsContext.cs
2017-07-27 12:03:55 -04:00

200 lines
6.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ShiftOS.Frontend.Apps;
namespace ShiftOS.Frontend.GraphicsSubsystem
{
public class GraphicsContext
{
public GraphicsDevice Device
{
get
{
return _graphicsDevice;
}
}
private int _startx = 0;
private int _starty = 0;
private int _maxwidth = 1;
private int _maxheight = 1;
public int X
{
get
{
return _startx;
}
set
{
_startx = value;
}
}
public int Y
{
get
{
return _starty;
}
set
{
_starty = value;
}
}
public int Width
{
get
{
return _maxwidth;
}
set
{
_maxwidth = value;
}
}
public int Height
{
get
{
return _maxheight;
}
set
{
_maxheight = value;
}
}
private GraphicsDevice _graphicsDevice;
private SpriteBatch _spritebatch;
public GraphicsContext(GraphicsDevice device, SpriteBatch batch, int x, int y, int width, int height)
{
_graphicsDevice = device;
_spritebatch = batch;
_maxwidth = width;
_maxheight = height;
_startx = x;
_starty = y;
}
public void Clear(Color c)
{
DrawRectangle(0, 0, _maxwidth, _maxheight, c);
}
public void DrawLine(int x, int y, int x1, int y1, int thickness, Texture2D tex2)
{
x += _startx;
y += _starty;
int distance = (int)Vector2.Distance(new Vector2(x, y), new Vector2(x1, y1));
float rotation = getRotation(x, y, x1, y1);
_spritebatch.Draw(tex2, new Rectangle(x, y, distance, thickness), null, Color.White, rotation, Vector2.Zero, SpriteEffects.None, 0);
}
public void DrawLine(int x, int y, int x1, int y1, int thickness, Color color)
{
x += _startx;
y += _starty;
int distance = (int)Vector2.Distance(new Vector2(x, y), new Vector2(x1, y1));
float rotation = getRotation(x, y, x1, y1);
_spritebatch.Draw(UIManager.SkinTextures["PureWhite"], new Rectangle(x, y, distance, thickness), null, color, rotation, Vector2.Zero, SpriteEffects.None, 0);
}
public void DrawRectangle(int x, int y, int width, int height, Color color)
{
x += _startx;
y += _starty;
_spritebatch.Draw(UIManager.SkinTextures["PureWhite"], new Rectangle(x, y, width, height), color);
}
public void DrawRectangle(int x, int y, int width, int height, Texture2D tex2)
{
x += _startx;
y += _starty;
_spritebatch.Draw(tex2, new Rectangle(x, y, width, height), Color.White);
}
public Vector2 MeasureString(string text, System.Drawing.Font font, int wrapWidth = int.MaxValue)
{
using(var gfx = System.Drawing.Graphics.FromImage(new System.Drawing.Bitmap(1, 1)))
{
var s = gfx.SmartMeasureString(text, font, wrapWidth);
return new Vector2((float)Math.Ceiling(s.Width), (float)Math.Ceiling(s.Height));
}
}
public static List<TextCache> StringCaches = new List<TextCache>();
public void DrawString(string text, int x, int y, Color color, System.Drawing.Font font, int wrapWidth = 0)
{
x += _startx;
y += _starty;
var fontcache = StringCaches.FirstOrDefault(z => z.Text == text && z.FontFamily == font&&z.WrapWidth == wrapWidth);
if (fontcache == null)
{
Vector2 measure;
if (wrapWidth == 0)
measure = MeasureString(text, font);
else
measure = MeasureString(text, font, wrapWidth);
using(var bmp = new System.Drawing.Bitmap((int)measure.X, (int)measure.Y))
{
using(var gfx = System.Drawing.Graphics.FromImage(bmp))
{
var sFormat = System.Drawing.StringFormat.GenericTypographic;
sFormat.FormatFlags |= System.Drawing.StringFormatFlags.NoClip;
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
gfx.DrawString(text, font, System.Drawing.Brushes.White, new System.Drawing.RectangleF(0, 0, bmp.Width, bmp.Height), sFormat);
}
var lck = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var data = new byte[Math.Abs(lck.Stride) * lck.Height];
System.Runtime.InteropServices.Marshal.Copy(lck.Scan0, data, 0, data.Length);
var tex2 = new Texture2D(_graphicsDevice, bmp.Width, bmp.Height);
tex2.SetData<byte>(data);
fontcache = new TextCache();
fontcache.Text = text;
fontcache.FontFamily = font;
fontcache.WrapWidth = wrapWidth;
fontcache.Cache = tex2;
StringCaches.Add(fontcache);
}
}
_spritebatch.Draw(fontcache.Cache, new Rectangle(x, y, fontcache.Cache.Width, fontcache.Cache.Height), color);
}
private float getRotation(float x, float y, float x2, float y2)
{
float adj = x - x2;
float opp = y - y2;
float tan = opp / adj;
float res = MathHelper.ToDegrees((float)Math.Atan2(opp, adj));
res = (res - 180) % 360;
if (res < 0) { res += 360; }
res = MathHelper.ToRadians(res);
return res;
}
}
public class TextCache
{
public string Text { get; set; }
public System.Drawing.Font FontFamily { get; set; }
public Texture2D Cache { get; set; }
public int WrapWidth { get; set; }
}
}